@swarmvaultai/engine 0.7.25 → 0.7.26
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/LICENSE +21 -0
- package/dist/chunk-N56FAH4N.js +1404 -0
- package/dist/chunk-ZQ5T64AR.js +1365 -0
- package/dist/hooks/claude.js +0 -0
- package/dist/hooks/copilot.js +0 -0
- package/dist/hooks/gemini.js +0 -0
- package/dist/index.d.ts +20 -3
- package/dist/index.js +481 -122
- package/dist/registry-FKEREVDO.js +12 -0
- package/dist/registry-SYCRRA65.js +12 -0
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
uniqueBy,
|
|
23
23
|
writeFileIfChanged,
|
|
24
24
|
writeJsonFile
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-N56FAH4N.js";
|
|
26
26
|
import {
|
|
27
27
|
estimatePageTokens,
|
|
28
28
|
estimateTokens,
|
|
@@ -495,6 +495,7 @@ async function autoCommitWikiChanges(rootDir, operation, detail, options) {
|
|
|
495
495
|
// src/graph-export.ts
|
|
496
496
|
import fs2 from "fs/promises";
|
|
497
497
|
import path2 from "path";
|
|
498
|
+
import matter from "gray-matter";
|
|
498
499
|
|
|
499
500
|
// src/graph-interchange.ts
|
|
500
501
|
function exportHyperedgeNodeId(hyperedge) {
|
|
@@ -1593,14 +1594,27 @@ function deduplicateFileName(baseName, used) {
|
|
|
1593
1594
|
used.add(name);
|
|
1594
1595
|
return name;
|
|
1595
1596
|
}
|
|
1596
|
-
|
|
1597
|
-
const
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1597
|
+
function typePluralDir(nodeType) {
|
|
1598
|
+
const map = {
|
|
1599
|
+
source: "sources",
|
|
1600
|
+
module: "modules",
|
|
1601
|
+
symbol: "symbols",
|
|
1602
|
+
concept: "concepts",
|
|
1603
|
+
entity: "entities",
|
|
1604
|
+
rationale: "rationales"
|
|
1605
|
+
};
|
|
1606
|
+
return map[nodeType] ?? "other";
|
|
1607
|
+
}
|
|
1608
|
+
function obsidianNodeSlug(node, pageById2) {
|
|
1609
|
+
if (node.pageId) {
|
|
1610
|
+
const page = pageById2.get(node.pageId);
|
|
1611
|
+
if (page) return path2.basename(page.path, ".md");
|
|
1612
|
+
}
|
|
1613
|
+
return slugify(node.label);
|
|
1614
|
+
}
|
|
1615
|
+
function buildAdjacency(edges) {
|
|
1602
1616
|
const adjacency = /* @__PURE__ */ new Map();
|
|
1603
|
-
for (const edge of
|
|
1617
|
+
for (const edge of edges) {
|
|
1604
1618
|
if (!adjacency.has(edge.source)) adjacency.set(edge.source, []);
|
|
1605
1619
|
if (!adjacency.has(edge.target)) adjacency.set(edge.target, []);
|
|
1606
1620
|
adjacency.get(edge.source).push({
|
|
@@ -1618,44 +1632,164 @@ async function exportObsidianVault(rootDir, outputDir) {
|
|
|
1618
1632
|
direction: "in"
|
|
1619
1633
|
});
|
|
1620
1634
|
}
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1635
|
+
return adjacency;
|
|
1636
|
+
}
|
|
1637
|
+
async function listFilesRecursive2(dir, base = "") {
|
|
1638
|
+
const results = [];
|
|
1639
|
+
let entries;
|
|
1640
|
+
try {
|
|
1641
|
+
entries = await fs2.readdir(dir, { withFileTypes: true });
|
|
1642
|
+
} catch {
|
|
1643
|
+
return results;
|
|
1626
1644
|
}
|
|
1627
|
-
|
|
1645
|
+
for (const entry of entries) {
|
|
1646
|
+
const rel = base ? `${base}/${entry.name}` : entry.name;
|
|
1647
|
+
if (entry.isDirectory()) {
|
|
1648
|
+
results.push(...await listFilesRecursive2(path2.join(dir, entry.name), rel));
|
|
1649
|
+
} else {
|
|
1650
|
+
results.push(rel);
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
return results;
|
|
1654
|
+
}
|
|
1655
|
+
function connectionsSection(nodeIds, adjacency, nodesById, wikilinkTarget) {
|
|
1656
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1657
|
+
const lines = [];
|
|
1658
|
+
for (const nodeId of nodeIds) {
|
|
1659
|
+
for (const entry of adjacency.get(nodeId) ?? []) {
|
|
1660
|
+
const key = `${entry.neighborId}:${entry.relation}`;
|
|
1661
|
+
if (seen.has(key)) continue;
|
|
1662
|
+
seen.add(key);
|
|
1663
|
+
const neighbor = nodesById.get(entry.neighborId);
|
|
1664
|
+
if (!neighbor) continue;
|
|
1665
|
+
const target = wikilinkTarget.get(entry.neighborId);
|
|
1666
|
+
if (!target) continue;
|
|
1667
|
+
lines.push(`- [[${target}|${neighbor.label}]] \u2014 ${entry.relation} (${entry.evidenceClass}, ${entry.confidence.toFixed(2)})`);
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
return lines;
|
|
1671
|
+
}
|
|
1672
|
+
async function exportObsidianVault(rootDir, outputDir) {
|
|
1673
|
+
const graph = await loadGraph(rootDir);
|
|
1674
|
+
const { paths } = await loadVaultConfig(rootDir);
|
|
1675
|
+
const resolvedOutputDir = path2.resolve(outputDir);
|
|
1676
|
+
await ensureDir(resolvedOutputDir);
|
|
1677
|
+
const nodesById = graphNodeById(graph);
|
|
1678
|
+
const pageById2 = graphPageById(graph);
|
|
1679
|
+
const communities = sortedCommunities(graph);
|
|
1680
|
+
const adjacency = buildAdjacency(graph.edges);
|
|
1681
|
+
const nodesByPageId = /* @__PURE__ */ new Map();
|
|
1628
1682
|
for (const node of graph.nodes) {
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
if (
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
const neighborFile = nodeFileName.get(neighbor.neighborId) ?? safeFileName(neighborNode.label);
|
|
1650
|
-
lines.push(`- [[${neighborFile}]] \u2014 ${neighbor.relation} (${neighbor.evidenceClass}, ${neighbor.confidence.toFixed(2)})`);
|
|
1683
|
+
if (node.pageId && pageById2.has(node.pageId)) {
|
|
1684
|
+
const list = nodesByPageId.get(node.pageId) ?? [];
|
|
1685
|
+
list.push(node);
|
|
1686
|
+
nodesByPageId.set(node.pageId, list);
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
const orphanNodes = graph.nodes.filter((node) => !node.pageId || !pageById2.has(node.pageId));
|
|
1690
|
+
const usedOrphanSlugs = /* @__PURE__ */ new Set();
|
|
1691
|
+
const orphanFilePath = /* @__PURE__ */ new Map();
|
|
1692
|
+
for (const node of [...orphanNodes].sort((a, b) => a.label.localeCompare(b.label) || a.id.localeCompare(b.id))) {
|
|
1693
|
+
const slug = deduplicateFileName(obsidianNodeSlug(node, pageById2), usedOrphanSlugs);
|
|
1694
|
+
orphanFilePath.set(node.id, `graph/nodes/${typePluralDir(node.type)}/${slug}.md`);
|
|
1695
|
+
}
|
|
1696
|
+
const wikilinkTarget = /* @__PURE__ */ new Map();
|
|
1697
|
+
for (const node of graph.nodes) {
|
|
1698
|
+
if (node.pageId) {
|
|
1699
|
+
const page = pageById2.get(node.pageId);
|
|
1700
|
+
if (page) {
|
|
1701
|
+
wikilinkTarget.set(node.id, page.path.replace(/\.md$/, ""));
|
|
1702
|
+
continue;
|
|
1651
1703
|
}
|
|
1652
|
-
lines.push("");
|
|
1653
1704
|
}
|
|
1654
|
-
|
|
1705
|
+
const orphanPath = orphanFilePath.get(node.id);
|
|
1706
|
+
if (orphanPath) {
|
|
1707
|
+
wikilinkTarget.set(node.id, orphanPath.replace(/\.md$/, ""));
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
let fileCount = 0;
|
|
1711
|
+
const wikiFiles = await listFilesRecursive2(paths.wikiDir);
|
|
1712
|
+
const pageByPath = new Map(graph.pages.map((p) => [p.path, p]));
|
|
1713
|
+
for (const relPath of wikiFiles) {
|
|
1714
|
+
if (!relPath.endsWith(".md")) continue;
|
|
1715
|
+
const srcFile = path2.join(paths.wikiDir, relPath);
|
|
1716
|
+
const destFile = path2.join(resolvedOutputDir, relPath);
|
|
1717
|
+
await ensureDir(path2.dirname(destFile));
|
|
1718
|
+
let rawContent;
|
|
1719
|
+
try {
|
|
1720
|
+
rawContent = await fs2.readFile(srcFile, "utf8");
|
|
1721
|
+
} catch {
|
|
1722
|
+
continue;
|
|
1723
|
+
}
|
|
1724
|
+
const matchingPage = pageByPath.get(relPath);
|
|
1725
|
+
const pageNodes = matchingPage ? nodesByPageId.get(matchingPage.id) ?? [] : [];
|
|
1726
|
+
const parsed = matter(rawContent);
|
|
1727
|
+
const data = parsed.data;
|
|
1728
|
+
if (pageNodes.length > 0) {
|
|
1729
|
+
const primaryNode = pageNodes[0];
|
|
1730
|
+
if (primaryNode.communityId) {
|
|
1731
|
+
data.graph_community = primaryNode.communityId;
|
|
1732
|
+
}
|
|
1733
|
+
const title = data.title ?? "";
|
|
1734
|
+
const nodeAliases = pageNodes.map((n) => n.label).filter((label) => label.toLowerCase() !== title.toLowerCase());
|
|
1735
|
+
const existingAliases = Array.isArray(data.aliases) ? data.aliases : [];
|
|
1736
|
+
const mergedAliases = [.../* @__PURE__ */ new Set([...existingAliases, ...nodeAliases])];
|
|
1737
|
+
if (mergedAliases.length > 0) {
|
|
1738
|
+
data.aliases = mergedAliases;
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
let outputContent = matter.stringify(parsed.content, data);
|
|
1742
|
+
if (pageNodes.length > 0) {
|
|
1743
|
+
const connLines = connectionsSection(
|
|
1744
|
+
pageNodes.map((n) => n.id),
|
|
1745
|
+
adjacency,
|
|
1746
|
+
nodesById,
|
|
1747
|
+
wikilinkTarget
|
|
1748
|
+
);
|
|
1749
|
+
if (connLines.length > 0) {
|
|
1750
|
+
outputContent = `${outputContent.trimEnd()}
|
|
1751
|
+
|
|
1752
|
+
## Graph Connections
|
|
1753
|
+
|
|
1754
|
+
${connLines.join("\n")}
|
|
1755
|
+
`;
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
await fs2.writeFile(destFile, outputContent, "utf8");
|
|
1759
|
+
fileCount++;
|
|
1760
|
+
}
|
|
1761
|
+
for (const node of orphanNodes) {
|
|
1762
|
+
const relPath = orphanFilePath.get(node.id);
|
|
1763
|
+
const destFile = path2.join(resolvedOutputDir, relPath);
|
|
1764
|
+
await ensureDir(path2.dirname(destFile));
|
|
1765
|
+
const slug = path2.basename(relPath, ".md");
|
|
1766
|
+
const aliases = node.label !== slug ? [node.label] : [];
|
|
1767
|
+
const frontmatter = {
|
|
1768
|
+
id: node.id,
|
|
1769
|
+
type: node.type,
|
|
1770
|
+
community: node.communityId ?? null,
|
|
1771
|
+
confidence: node.confidence ?? null,
|
|
1772
|
+
source_class: node.sourceClass ?? null,
|
|
1773
|
+
tags: node.tags ?? []
|
|
1774
|
+
};
|
|
1775
|
+
if (aliases.length > 0) {
|
|
1776
|
+
frontmatter.aliases = aliases;
|
|
1777
|
+
}
|
|
1778
|
+
const lines = [`# ${node.label}`, ""];
|
|
1779
|
+
const connLines = connectionsSection([node.id], adjacency, nodesById, wikilinkTarget);
|
|
1780
|
+
if (connLines.length > 0) {
|
|
1781
|
+
lines.push("## Connections", "", ...connLines, "");
|
|
1782
|
+
}
|
|
1783
|
+
const content = matter.stringify(lines.join("\n"), frontmatter);
|
|
1784
|
+
await fs2.writeFile(destFile, content, "utf8");
|
|
1655
1785
|
fileCount++;
|
|
1656
1786
|
}
|
|
1657
1787
|
const usedCommunityFileNames = /* @__PURE__ */ new Set();
|
|
1658
1788
|
for (const community of communities) {
|
|
1789
|
+
const wikiCommunityPage = graph.pages.find(
|
|
1790
|
+
(p) => p.kind === "community_summary" && p.nodeIds.some((nid) => community.nodeIds.includes(nid))
|
|
1791
|
+
);
|
|
1792
|
+
if (wikiCommunityPage) continue;
|
|
1659
1793
|
const memberNodes = community.nodeIds.map((id) => nodesById.get(id)).filter((n2) => Boolean(n2));
|
|
1660
1794
|
const memberIdSet = new Set(community.nodeIds);
|
|
1661
1795
|
let internalEdges = 0;
|
|
@@ -1674,35 +1808,102 @@ async function exportObsidianVault(rootDir, outputDir) {
|
|
|
1674
1808
|
return nbNode && nbNode.communityId !== community.id;
|
|
1675
1809
|
});
|
|
1676
1810
|
});
|
|
1677
|
-
const
|
|
1678
|
-
const
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
`node_count: ${memberNodes.length}`,
|
|
1682
|
-
`cohesion: ${cohesion.toFixed(4)}`,
|
|
1683
|
-
"---",
|
|
1684
|
-
"",
|
|
1685
|
-
`# ${community.label}`,
|
|
1686
|
-
"",
|
|
1687
|
-
"## Members",
|
|
1688
|
-
""
|
|
1689
|
-
];
|
|
1811
|
+
const communitySlug = deduplicateFileName(safeFileName(community.label), usedCommunityFileNames);
|
|
1812
|
+
const destFile = path2.join(resolvedOutputDir, "graph", "communities", `${communitySlug}.md`);
|
|
1813
|
+
await ensureDir(path2.dirname(destFile));
|
|
1814
|
+
const lines = [`# ${community.label}`, "", "## Members", ""];
|
|
1690
1815
|
for (const member of memberNodes) {
|
|
1691
|
-
const
|
|
1692
|
-
|
|
1816
|
+
const target = wikilinkTarget.get(member.id);
|
|
1817
|
+
if (target) {
|
|
1818
|
+
lines.push(`- [[${target}|${member.label}]]`);
|
|
1819
|
+
} else {
|
|
1820
|
+
lines.push(`- ${member.label}`);
|
|
1821
|
+
}
|
|
1693
1822
|
}
|
|
1694
1823
|
lines.push("");
|
|
1695
1824
|
if (bridgeNodes.length > 0) {
|
|
1696
1825
|
lines.push("## Bridge Nodes", "");
|
|
1697
1826
|
for (const bridge of bridgeNodes) {
|
|
1698
|
-
const
|
|
1699
|
-
|
|
1827
|
+
const target = wikilinkTarget.get(bridge.id);
|
|
1828
|
+
if (target) {
|
|
1829
|
+
lines.push(`- [[${target}|${bridge.label}]]`);
|
|
1830
|
+
} else {
|
|
1831
|
+
lines.push(`- ${bridge.label}`);
|
|
1832
|
+
}
|
|
1700
1833
|
}
|
|
1701
1834
|
lines.push("");
|
|
1702
1835
|
}
|
|
1703
|
-
|
|
1836
|
+
const frontmatter = {
|
|
1837
|
+
id: community.id,
|
|
1838
|
+
node_count: memberNodes.length,
|
|
1839
|
+
cohesion: Number(cohesion.toFixed(4))
|
|
1840
|
+
};
|
|
1841
|
+
const content = matter.stringify(lines.join("\n"), frontmatter);
|
|
1842
|
+
await fs2.writeFile(destFile, content, "utf8");
|
|
1704
1843
|
fileCount++;
|
|
1705
1844
|
}
|
|
1845
|
+
const outputsAssetsDir = path2.join(paths.wikiDir, "outputs", "assets");
|
|
1846
|
+
try {
|
|
1847
|
+
const assetFiles = await listFilesRecursive2(outputsAssetsDir);
|
|
1848
|
+
for (const relAsset of assetFiles) {
|
|
1849
|
+
const src = path2.join(outputsAssetsDir, relAsset);
|
|
1850
|
+
const dest = path2.join(resolvedOutputDir, "outputs", "assets", relAsset);
|
|
1851
|
+
await ensureDir(path2.dirname(dest));
|
|
1852
|
+
await fs2.copyFile(src, dest);
|
|
1853
|
+
fileCount++;
|
|
1854
|
+
}
|
|
1855
|
+
} catch {
|
|
1856
|
+
}
|
|
1857
|
+
try {
|
|
1858
|
+
const rawAssetFiles = await listFilesRecursive2(paths.rawAssetsDir);
|
|
1859
|
+
for (const relAsset of rawAssetFiles) {
|
|
1860
|
+
const src = path2.join(paths.rawAssetsDir, relAsset);
|
|
1861
|
+
const dest = path2.join(resolvedOutputDir, "raw", "assets", relAsset);
|
|
1862
|
+
await ensureDir(path2.dirname(dest));
|
|
1863
|
+
await fs2.copyFile(src, dest);
|
|
1864
|
+
fileCount++;
|
|
1865
|
+
}
|
|
1866
|
+
} catch {
|
|
1867
|
+
}
|
|
1868
|
+
const obsidianDir = path2.join(resolvedOutputDir, ".obsidian");
|
|
1869
|
+
await ensureDir(obsidianDir);
|
|
1870
|
+
const projectIds = Object.keys(
|
|
1871
|
+
graph.pages.reduce(
|
|
1872
|
+
(acc, page) => {
|
|
1873
|
+
for (const pid of page.projectIds) acc[pid] = true;
|
|
1874
|
+
return acc;
|
|
1875
|
+
},
|
|
1876
|
+
{}
|
|
1877
|
+
)
|
|
1878
|
+
);
|
|
1879
|
+
const colorGroups = projectIds.map((pid, index) => ({
|
|
1880
|
+
query: `tag:#project/${pid}`,
|
|
1881
|
+
color: ["#0ea5e9", "#22c55e", "#f59e0b", "#8b5cf6", "#fb7185", "#14b8a6"][index % 6]
|
|
1882
|
+
}));
|
|
1883
|
+
await fs2.writeFile(
|
|
1884
|
+
path2.join(obsidianDir, "app.json"),
|
|
1885
|
+
JSON.stringify(
|
|
1886
|
+
{ newFileLocation: "folder", newFileFolderPath: "outputs", attachmentFolderPath: "raw/assets", useMarkdownLinks: false },
|
|
1887
|
+
null,
|
|
1888
|
+
2
|
|
1889
|
+
),
|
|
1890
|
+
"utf8"
|
|
1891
|
+
);
|
|
1892
|
+
await fs2.writeFile(
|
|
1893
|
+
path2.join(obsidianDir, "core-plugins.json"),
|
|
1894
|
+
JSON.stringify(["file-explorer", "global-search", "graph", "backlink", "tag-pane", "page-preview", "outline"], null, 2),
|
|
1895
|
+
"utf8"
|
|
1896
|
+
);
|
|
1897
|
+
await fs2.writeFile(
|
|
1898
|
+
path2.join(obsidianDir, "graph.json"),
|
|
1899
|
+
JSON.stringify(
|
|
1900
|
+
{ colorGroups, "collapse-filter": false, search: "", showTags: true, showAttachments: false, showOrphans: true },
|
|
1901
|
+
null,
|
|
1902
|
+
2
|
|
1903
|
+
),
|
|
1904
|
+
"utf8"
|
|
1905
|
+
);
|
|
1906
|
+
fileCount += 3;
|
|
1706
1907
|
return { format: "obsidian", outputPath: resolvedOutputDir, fileCount };
|
|
1707
1908
|
}
|
|
1708
1909
|
async function exportObsidianCanvas(rootDir, outputPath) {
|
|
@@ -2782,7 +2983,7 @@ import fs11 from "fs/promises";
|
|
|
2782
2983
|
import path12 from "path";
|
|
2783
2984
|
import { pathToFileURL } from "url";
|
|
2784
2985
|
import { Readability } from "@mozilla/readability";
|
|
2785
|
-
import
|
|
2986
|
+
import matter4 from "gray-matter";
|
|
2786
2987
|
import ignore from "ignore";
|
|
2787
2988
|
import { isText } from "istextorbinary";
|
|
2788
2989
|
import { JSDOM as JSDOM2 } from "jsdom";
|
|
@@ -6272,7 +6473,7 @@ function htmlCodeAnalysis(manifest, rootNode, diagnostics) {
|
|
|
6272
6473
|
}
|
|
6273
6474
|
continue;
|
|
6274
6475
|
}
|
|
6275
|
-
if (tagName
|
|
6476
|
+
if (tagName?.includes("-")) {
|
|
6276
6477
|
if (!seenSymbolNames.has(tagName)) {
|
|
6277
6478
|
seenSymbolNames.add(tagName);
|
|
6278
6479
|
draftSymbols.push({
|
|
@@ -8039,6 +8240,7 @@ import { parse as parseCsvSync } from "csv-parse/sync";
|
|
|
8039
8240
|
import { strFromU8, unzipSync } from "fflate";
|
|
8040
8241
|
import { JSDOM } from "jsdom";
|
|
8041
8242
|
import TurndownService from "turndown";
|
|
8243
|
+
import { fetchTranscript } from "youtube-transcript-plus";
|
|
8042
8244
|
import { z } from "zod";
|
|
8043
8245
|
|
|
8044
8246
|
// src/markdown-ast.ts
|
|
@@ -8237,6 +8439,107 @@ async function extractImageWithVision(rootDir, input) {
|
|
|
8237
8439
|
await attachment.cleanup();
|
|
8238
8440
|
}
|
|
8239
8441
|
}
|
|
8442
|
+
async function extractAudioTranscription(rootDir, input) {
|
|
8443
|
+
let provider;
|
|
8444
|
+
try {
|
|
8445
|
+
provider = await getProviderForTask(rootDir, "audioProvider");
|
|
8446
|
+
} catch (error) {
|
|
8447
|
+
return {
|
|
8448
|
+
artifact: {
|
|
8449
|
+
...extractionMetadata("audio", input.mimeType, "audio_transcription"),
|
|
8450
|
+
warnings: [`Audio transcription unavailable: ${error instanceof Error ? error.message : "provider not configured"}`]
|
|
8451
|
+
}
|
|
8452
|
+
};
|
|
8453
|
+
}
|
|
8454
|
+
if (!provider.capabilities.has("audio") || !provider.transcribeAudio) {
|
|
8455
|
+
return {
|
|
8456
|
+
artifact: {
|
|
8457
|
+
...extractionMetadata("audio", input.mimeType, "audio_transcription"),
|
|
8458
|
+
warnings: [`Audio transcription unavailable for provider ${provider.id}. Configure a provider with audio capability.`]
|
|
8459
|
+
}
|
|
8460
|
+
};
|
|
8461
|
+
}
|
|
8462
|
+
try {
|
|
8463
|
+
const result = await provider.transcribeAudio({
|
|
8464
|
+
mimeType: input.mimeType,
|
|
8465
|
+
bytes: input.bytes,
|
|
8466
|
+
fileName: input.fileName
|
|
8467
|
+
});
|
|
8468
|
+
const metadata = {};
|
|
8469
|
+
if (result.duration !== void 0) {
|
|
8470
|
+
metadata.duration = String(result.duration);
|
|
8471
|
+
}
|
|
8472
|
+
if (result.language) {
|
|
8473
|
+
metadata.language = result.language;
|
|
8474
|
+
}
|
|
8475
|
+
return {
|
|
8476
|
+
extractedText: result.text || void 0,
|
|
8477
|
+
artifact: {
|
|
8478
|
+
...extractionMetadata("audio", input.mimeType, "audio_transcription"),
|
|
8479
|
+
providerId: provider.id,
|
|
8480
|
+
providerModel: provider.model,
|
|
8481
|
+
metadata: Object.keys(metadata).length ? metadata : void 0
|
|
8482
|
+
}
|
|
8483
|
+
};
|
|
8484
|
+
} catch (error) {
|
|
8485
|
+
return {
|
|
8486
|
+
artifact: {
|
|
8487
|
+
...extractionMetadata("audio", input.mimeType, "audio_transcription"),
|
|
8488
|
+
providerId: provider.id,
|
|
8489
|
+
providerModel: provider.model,
|
|
8490
|
+
warnings: [`Audio transcription failed: ${error instanceof Error ? truncate(error.message, 240) : "unknown error"}`]
|
|
8491
|
+
}
|
|
8492
|
+
};
|
|
8493
|
+
}
|
|
8494
|
+
}
|
|
8495
|
+
async function extractYoutubeTranscript(input) {
|
|
8496
|
+
try {
|
|
8497
|
+
const result = await fetchTranscript(input.videoId, { videoDetails: true });
|
|
8498
|
+
const details = result.videoDetails;
|
|
8499
|
+
const title = details?.title ?? `YouTube ${input.videoId}`;
|
|
8500
|
+
const transcriptText = result.segments?.map((part) => part.text).join(" ") ?? "";
|
|
8501
|
+
const sections = [`# ${title}`];
|
|
8502
|
+
const metaLines = [];
|
|
8503
|
+
if (details?.author) metaLines.push(`**Author:** ${details.author}`);
|
|
8504
|
+
if (details?.lengthSeconds) {
|
|
8505
|
+
const seconds = details.lengthSeconds;
|
|
8506
|
+
const minutes = Math.floor(seconds / 60);
|
|
8507
|
+
const secs = seconds % 60;
|
|
8508
|
+
metaLines.push(`**Duration:** ${minutes}:${String(secs).padStart(2, "0")}`);
|
|
8509
|
+
}
|
|
8510
|
+
if (details?.viewCount) metaLines.push(`**Views:** ${Number(details.viewCount).toLocaleString()}`);
|
|
8511
|
+
metaLines.push(`**URL:** ${input.url}`);
|
|
8512
|
+
if (metaLines.length) {
|
|
8513
|
+
sections.push(metaLines.join("\n"));
|
|
8514
|
+
}
|
|
8515
|
+
if (transcriptText.trim()) {
|
|
8516
|
+
sections.push(`## Transcript
|
|
8517
|
+
|
|
8518
|
+
${transcriptText.trim()}`);
|
|
8519
|
+
}
|
|
8520
|
+
const extractedText = sections.join("\n\n");
|
|
8521
|
+
const metadata = {};
|
|
8522
|
+
if (details?.title) metadata.title = details.title;
|
|
8523
|
+
if (details?.author) metadata.author = details.author;
|
|
8524
|
+
if (details?.lengthSeconds) metadata.duration = String(details.lengthSeconds);
|
|
8525
|
+
if (details?.viewCount) metadata.viewCount = String(details.viewCount);
|
|
8526
|
+
return {
|
|
8527
|
+
title,
|
|
8528
|
+
extractedText: extractedText || void 0,
|
|
8529
|
+
artifact: {
|
|
8530
|
+
...extractionMetadata("youtube", "text/html", "youtube_transcript"),
|
|
8531
|
+
metadata: Object.keys(metadata).length ? metadata : void 0
|
|
8532
|
+
}
|
|
8533
|
+
};
|
|
8534
|
+
} catch (error) {
|
|
8535
|
+
return {
|
|
8536
|
+
artifact: {
|
|
8537
|
+
...extractionMetadata("youtube", "text/html", "youtube_transcript"),
|
|
8538
|
+
warnings: [`YouTube transcript extraction failed: ${error instanceof Error ? truncate(error.message, 240) : "unknown error"}`]
|
|
8539
|
+
}
|
|
8540
|
+
};
|
|
8541
|
+
}
|
|
8542
|
+
}
|
|
8240
8543
|
function normalizePdfMetadata(raw) {
|
|
8241
8544
|
if (!raw || typeof raw !== "object") {
|
|
8242
8545
|
return void 0;
|
|
@@ -10034,7 +10337,7 @@ async function extractSlackExportDirectory(directoryPath) {
|
|
|
10034
10337
|
// src/logs.ts
|
|
10035
10338
|
import fs8 from "fs/promises";
|
|
10036
10339
|
import path8 from "path";
|
|
10037
|
-
import
|
|
10340
|
+
import matter2 from "gray-matter";
|
|
10038
10341
|
async function resolveUniqueSessionPath(rootDir, operation, title, startedAt) {
|
|
10039
10342
|
const { paths } = await initWorkspace(rootDir);
|
|
10040
10343
|
await ensureDir(paths.sessionsDir);
|
|
@@ -10087,7 +10390,7 @@ async function recordSession(rootDir, input) {
|
|
|
10087
10390
|
token_usage: input.tokenUsage
|
|
10088
10391
|
}).filter(([, value]) => value !== void 0)
|
|
10089
10392
|
);
|
|
10090
|
-
const content =
|
|
10393
|
+
const content = matter2.stringify(
|
|
10091
10394
|
[
|
|
10092
10395
|
`# ${input.operation[0]?.toUpperCase() ?? ""}${input.operation.slice(1)} Session`,
|
|
10093
10396
|
"",
|
|
@@ -10308,7 +10611,7 @@ async function managedSourceWorkingDir(rootDir, sourceId) {
|
|
|
10308
10611
|
// src/watch-state.ts
|
|
10309
10612
|
import fs10 from "fs/promises";
|
|
10310
10613
|
import path11 from "path";
|
|
10311
|
-
import
|
|
10614
|
+
import matter3 from "gray-matter";
|
|
10312
10615
|
function pendingEntryKey(entry) {
|
|
10313
10616
|
return entry.path;
|
|
10314
10617
|
}
|
|
@@ -10420,13 +10723,13 @@ async function markPagesStaleForSources(rootDir, sourceIds) {
|
|
|
10420
10723
|
continue;
|
|
10421
10724
|
}
|
|
10422
10725
|
const raw = await fs10.readFile(absolutePath, "utf8");
|
|
10423
|
-
const parsed =
|
|
10726
|
+
const parsed = matter3(raw);
|
|
10424
10727
|
if (parsed.data.freshness === "stale") {
|
|
10425
10728
|
continue;
|
|
10426
10729
|
}
|
|
10427
10730
|
parsed.data.freshness = "stale";
|
|
10428
10731
|
parsed.data.updated_at = now;
|
|
10429
|
-
await writeFileIfChanged(absolutePath,
|
|
10732
|
+
await writeFileIfChanged(absolutePath, matter3.stringify(parsed.content, parsed.data));
|
|
10430
10733
|
}
|
|
10431
10734
|
return affectedPagePaths;
|
|
10432
10735
|
}
|
|
@@ -10522,6 +10825,9 @@ function inferKind(mimeType, filePath, detectionOptions = {}) {
|
|
|
10522
10825
|
if (mimeType === "application/vnd.openxmlformats-officedocument.presentationml.presentation" || mimeType === "application/vnd.ms-powerpoint.presentation.macroenabled.12" || mimeType === "application/vnd.ms-powerpoint.template.macroenabled.12" || mimeType === "application/vnd.openxmlformats-officedocument.presentationml.template" || filePath.toLowerCase().endsWith(".pptx") || filePath.toLowerCase().endsWith(".pptm") || filePath.toLowerCase().endsWith(".potx") || filePath.toLowerCase().endsWith(".potm")) {
|
|
10523
10826
|
return "pptx";
|
|
10524
10827
|
}
|
|
10828
|
+
if (mimeType.startsWith("audio/") || /\.(mp3|wav|m4a|ogg|flac|webm|aac|wma)$/i.test(filePath)) {
|
|
10829
|
+
return "audio";
|
|
10830
|
+
}
|
|
10525
10831
|
if (mimeType.startsWith("image/") || isImagePath(filePath)) {
|
|
10526
10832
|
return "image";
|
|
10527
10833
|
}
|
|
@@ -10546,6 +10852,10 @@ var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
10546
10852
|
function isImagePath(filePath) {
|
|
10547
10853
|
return IMAGE_EXTENSIONS.has(path12.extname(filePath).toLowerCase());
|
|
10548
10854
|
}
|
|
10855
|
+
var YOUTUBE_URL_PATTERN = /(?:youtube\.com\/watch\?.*v=|youtu\.be\/|youtube\.com\/embed\/|youtube\.com\/shorts\/)([\w-]{11})/i;
|
|
10856
|
+
function parseYoutubeVideoId(url) {
|
|
10857
|
+
return url.match(YOUTUBE_URL_PATTERN)?.[1];
|
|
10858
|
+
}
|
|
10549
10859
|
function isStructuredTextMime(mimeType) {
|
|
10550
10860
|
switch (mimeType) {
|
|
10551
10861
|
case "application/json":
|
|
@@ -10813,7 +11123,7 @@ function normalizeSemanticMarkdownList(value) {
|
|
|
10813
11123
|
return items.length ? items : void 0;
|
|
10814
11124
|
}
|
|
10815
11125
|
function semanticMarkdownTitle(fallback, content, filePath) {
|
|
10816
|
-
const parsed =
|
|
11126
|
+
const parsed = matter4(content);
|
|
10817
11127
|
const frontmatterTitle = normalizeSemanticMarkdownScalar(parsed.data.title);
|
|
10818
11128
|
if (frontmatterTitle) {
|
|
10819
11129
|
return frontmatterTitle;
|
|
@@ -10821,7 +11131,7 @@ function semanticMarkdownTitle(fallback, content, filePath) {
|
|
|
10821
11131
|
return titleFromText(fallback, parsed.content, filePath);
|
|
10822
11132
|
}
|
|
10823
11133
|
function semanticMarkdownContent(content) {
|
|
10824
|
-
const parsed =
|
|
11134
|
+
const parsed = matter4(content);
|
|
10825
11135
|
const body = parsed.content.replace(/\r\n?/g, "\n").trim();
|
|
10826
11136
|
const semanticFrontmatter = Object.fromEntries(
|
|
10827
11137
|
MARKDOWN_SEMANTIC_FRONTMATTER_KEYS.flatMap((key) => {
|
|
@@ -11025,7 +11335,7 @@ function markdownFrontmatter(value) {
|
|
|
11025
11335
|
([, rawValue]) => Array.isArray(rawValue) ? rawValue.length > 0 : Boolean(typeof rawValue === "string" ? rawValue.trim() : rawValue)
|
|
11026
11336
|
)
|
|
11027
11337
|
);
|
|
11028
|
-
return
|
|
11338
|
+
return matter4.stringify("", normalized).trimEnd().split("\n").concat([""]);
|
|
11029
11339
|
}
|
|
11030
11340
|
function prepareCapturedMarkdownInput(input) {
|
|
11031
11341
|
return finalizePreparedInput({
|
|
@@ -11843,7 +12153,7 @@ function preparedMatchesManifest(manifest, prepared, contentHash) {
|
|
|
11843
12153
|
return manifest.contentHash === contentHash && manifest.extractionHash === (prepared.extractionHash ?? buildExtractionHash(prepared.extractedText, prepared.extractionArtifact)) && manifest.semanticHash === (prepared.semanticHash ?? contentHash) && manifest.title === prepared.title && manifest.sourceKind === prepared.sourceKind && manifest.sourceType === prepared.sourceType && manifest.sourceClass === prepared.sourceClass && manifest.language === prepared.language && manifest.mimeType === prepared.mimeType && manifest.repoRelativePath === prepared.repoRelativePath && manifest.sourceGroupId === prepared.sourceGroupId && manifest.sourceGroupTitle === prepared.sourceGroupTitle && manifest.sourcePartKey === prepared.sourcePartKey && manifest.partIndex === prepared.partIndex && manifest.partCount === prepared.partCount && manifest.partTitle === prepared.partTitle && JSON.stringify(manifest.details ?? {}) === JSON.stringify(prepared.details ?? {});
|
|
11844
12154
|
}
|
|
11845
12155
|
function shouldDeferWatchSemanticRefresh(sourceKind) {
|
|
11846
|
-
return sourceKind === "markdown" || sourceKind === "text" || sourceKind === "html" || sourceKind === "pdf" || sourceKind === "docx" || sourceKind === "epub" || sourceKind === "csv" || sourceKind === "xlsx" || sourceKind === "pptx" || sourceKind === "transcript" || sourceKind === "chat_export" || sourceKind === "email" || sourceKind === "calendar" || sourceKind === "image";
|
|
12156
|
+
return sourceKind === "markdown" || sourceKind === "text" || sourceKind === "html" || sourceKind === "pdf" || sourceKind === "docx" || sourceKind === "epub" || sourceKind === "csv" || sourceKind === "xlsx" || sourceKind === "pptx" || sourceKind === "transcript" || sourceKind === "chat_export" || sourceKind === "email" || sourceKind === "calendar" || sourceKind === "image" || sourceKind === "audio";
|
|
11847
12157
|
}
|
|
11848
12158
|
function pendingSemanticRefreshId(changeType, repoRoot, relativePath) {
|
|
11849
12159
|
return `pending:${changeType}:${sha256(`${toPosix(repoRoot)}:${relativePath}`).slice(0, 12)}`;
|
|
@@ -12334,6 +12644,15 @@ async function prepareFileInputs(rootDir, absoluteInput, repoRoot, sourceClass)
|
|
|
12334
12644
|
title = extracted.title?.trim() || title;
|
|
12335
12645
|
extractedText = extracted.extractedText;
|
|
12336
12646
|
extractionArtifact = extracted.artifact;
|
|
12647
|
+
} else if (sourceKind === "audio") {
|
|
12648
|
+
title = path12.basename(absoluteInput, path12.extname(absoluteInput));
|
|
12649
|
+
const extracted = await extractAudioTranscription(rootDir, {
|
|
12650
|
+
mimeType,
|
|
12651
|
+
bytes: payloadBytes,
|
|
12652
|
+
fileName: absoluteInput
|
|
12653
|
+
});
|
|
12654
|
+
extractedText = extracted.extractedText;
|
|
12655
|
+
extractionArtifact = extracted.artifact;
|
|
12337
12656
|
} else {
|
|
12338
12657
|
title = path12.basename(absoluteInput, path12.extname(absoluteInput));
|
|
12339
12658
|
}
|
|
@@ -12365,6 +12684,28 @@ async function prepareFileInput(rootDir, absoluteInput, repoRoot, sourceClass) {
|
|
|
12365
12684
|
}
|
|
12366
12685
|
async function prepareUrlInputs(rootDir, input, options) {
|
|
12367
12686
|
await validateUrlSafety(input);
|
|
12687
|
+
const youtubeVideoId = parseYoutubeVideoId(input);
|
|
12688
|
+
if (youtubeVideoId) {
|
|
12689
|
+
const extracted = await extractYoutubeTranscript({ videoId: youtubeVideoId, url: input });
|
|
12690
|
+
const title2 = extracted.title ?? `YouTube ${youtubeVideoId}`;
|
|
12691
|
+
const extractedText2 = extracted.extractedText;
|
|
12692
|
+
const payloadBytes2 = Buffer.from(extractedText2 ?? "", "utf8");
|
|
12693
|
+
return [
|
|
12694
|
+
finalizePreparedInput({
|
|
12695
|
+
title: title2,
|
|
12696
|
+
originType: "url",
|
|
12697
|
+
sourceKind: "youtube",
|
|
12698
|
+
url: normalizeOriginUrl(input),
|
|
12699
|
+
mimeType: "text/html",
|
|
12700
|
+
storedExtension: ".md",
|
|
12701
|
+
payloadBytes: payloadBytes2,
|
|
12702
|
+
extractedText: extractedText2,
|
|
12703
|
+
extractionArtifact: extracted.artifact,
|
|
12704
|
+
extractionHash: buildExtractionHash(extractedText2, extracted.artifact),
|
|
12705
|
+
details: extracted.artifact.metadata
|
|
12706
|
+
})
|
|
12707
|
+
];
|
|
12708
|
+
}
|
|
12368
12709
|
const response = await fetch(input);
|
|
12369
12710
|
if (!response.ok) {
|
|
12370
12711
|
throw new Error(`Failed to fetch ${input}: ${response.status} ${response.statusText}`);
|
|
@@ -12584,6 +12925,14 @@ async function prepareUrlInputs(rootDir, input, options) {
|
|
|
12584
12925
|
title = extracted.title?.trim() || title;
|
|
12585
12926
|
extractedText = extracted.extractedText;
|
|
12586
12927
|
extractionArtifact = extracted.artifact;
|
|
12928
|
+
} else if (sourceKind === "audio") {
|
|
12929
|
+
const extracted = await extractAudioTranscription(rootDir, {
|
|
12930
|
+
mimeType,
|
|
12931
|
+
bytes: payloadBytes,
|
|
12932
|
+
fileName: inputUrl.pathname
|
|
12933
|
+
});
|
|
12934
|
+
extractedText = extracted.extractedText;
|
|
12935
|
+
extractionArtifact = extracted.artifact;
|
|
12587
12936
|
}
|
|
12588
12937
|
}
|
|
12589
12938
|
return [
|
|
@@ -13171,7 +13520,7 @@ import fs19 from "fs/promises";
|
|
|
13171
13520
|
import path23 from "path";
|
|
13172
13521
|
import Graph from "graphology";
|
|
13173
13522
|
import louvain from "graphology-communities-louvain";
|
|
13174
|
-
import
|
|
13523
|
+
import matter10 from "gray-matter";
|
|
13175
13524
|
import { z as z7 } from "zod";
|
|
13176
13525
|
|
|
13177
13526
|
// src/analysis.ts
|
|
@@ -13607,7 +13956,7 @@ function conflictConfidence(claimA, claimB) {
|
|
|
13607
13956
|
// src/deep-lint.ts
|
|
13608
13957
|
import fs13 from "fs/promises";
|
|
13609
13958
|
import path17 from "path";
|
|
13610
|
-
import
|
|
13959
|
+
import matter5 from "gray-matter";
|
|
13611
13960
|
import { z as z5 } from "zod";
|
|
13612
13961
|
|
|
13613
13962
|
// src/findings.ts
|
|
@@ -13981,7 +14330,7 @@ async function loadContextPages(rootDir, graph) {
|
|
|
13981
14330
|
contextPages.slice(0, 18).map(async (page) => {
|
|
13982
14331
|
const absolutePath = path17.join(paths.wikiDir, page.path);
|
|
13983
14332
|
const raw = await fs13.readFile(absolutePath, "utf8").catch(() => "");
|
|
13984
|
-
const parsed =
|
|
14333
|
+
const parsed = matter5(raw);
|
|
13985
14334
|
return {
|
|
13986
14335
|
id: page.id,
|
|
13987
14336
|
title: page.title,
|
|
@@ -14917,7 +15266,7 @@ function enrichGraph(graph, manifests, analyses, extraSimilarityEdges = []) {
|
|
|
14917
15266
|
}
|
|
14918
15267
|
|
|
14919
15268
|
// src/markdown.ts
|
|
14920
|
-
import
|
|
15269
|
+
import matter6 from "gray-matter";
|
|
14921
15270
|
function uniqueStrings2(values) {
|
|
14922
15271
|
return uniqueBy(values.filter(Boolean), (value) => value);
|
|
14923
15272
|
}
|
|
@@ -15172,7 +15521,7 @@ function buildSourcePage(manifest, analysis, schemaHash, metadata, relatedOutput
|
|
|
15172
15521
|
compiledFrom: metadata.compiledFrom,
|
|
15173
15522
|
managedBy: metadata.managedBy
|
|
15174
15523
|
},
|
|
15175
|
-
content:
|
|
15524
|
+
content: matter6.stringify(body, safeFrontmatter(frontmatter))
|
|
15176
15525
|
};
|
|
15177
15526
|
}
|
|
15178
15527
|
function buildModulePage(input) {
|
|
@@ -15322,7 +15671,7 @@ function buildModulePage(input) {
|
|
|
15322
15671
|
compiledFrom: metadata.compiledFrom,
|
|
15323
15672
|
managedBy: metadata.managedBy
|
|
15324
15673
|
},
|
|
15325
|
-
content:
|
|
15674
|
+
content: matter6.stringify(body, frontmatter)
|
|
15326
15675
|
};
|
|
15327
15676
|
}
|
|
15328
15677
|
function buildAggregatePage(kind, name, descriptions, sourceAnalyses, sourceHashes, sourceSemanticHashes, schemaHash, metadata, relativePath, relatedOutputs = [], decorations, existingContent) {
|
|
@@ -15399,7 +15748,7 @@ function buildAggregatePage(kind, name, descriptions, sourceAnalyses, sourceHash
|
|
|
15399
15748
|
compiledFrom: metadata.compiledFrom,
|
|
15400
15749
|
managedBy: metadata.managedBy
|
|
15401
15750
|
},
|
|
15402
|
-
content:
|
|
15751
|
+
content: matter6.stringify(body, frontmatter)
|
|
15403
15752
|
};
|
|
15404
15753
|
}
|
|
15405
15754
|
function buildIndexPage(pages, schemaHash, metadata, projectPages = []) {
|
|
@@ -15483,7 +15832,7 @@ function buildIndexPage(pages, schemaHash, metadata, projectPages = []) {
|
|
|
15483
15832
|
}
|
|
15484
15833
|
function buildSectionIndex(kind, pages, schemaHash, metadata, projectIds = []) {
|
|
15485
15834
|
const title = kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
15486
|
-
return
|
|
15835
|
+
return matter6.stringify(
|
|
15487
15836
|
[`# ${title}`, "", ...pages.map((page) => `- [[${page.path.replace(/\.md$/, "")}|${page.title}]]`), ""].join("\n"),
|
|
15488
15837
|
{
|
|
15489
15838
|
page_id: `${kind}:index`,
|
|
@@ -15995,7 +16344,7 @@ function buildGraphReportPage(input) {
|
|
|
15995
16344
|
compiledFrom: input.metadata.compiledFrom,
|
|
15996
16345
|
managedBy: input.metadata.managedBy
|
|
15997
16346
|
},
|
|
15998
|
-
content:
|
|
16347
|
+
content: matter6.stringify(body, frontmatter)
|
|
15999
16348
|
};
|
|
16000
16349
|
}
|
|
16001
16350
|
function buildCommunitySummaryPage(input) {
|
|
@@ -16079,11 +16428,11 @@ function buildCommunitySummaryPage(input) {
|
|
|
16079
16428
|
compiledFrom: input.metadata.compiledFrom,
|
|
16080
16429
|
managedBy: input.metadata.managedBy
|
|
16081
16430
|
},
|
|
16082
|
-
content:
|
|
16431
|
+
content: matter6.stringify(body, frontmatter)
|
|
16083
16432
|
};
|
|
16084
16433
|
}
|
|
16085
16434
|
function buildProjectsIndex(projectPages, schemaHash, metadata) {
|
|
16086
|
-
return
|
|
16435
|
+
return matter6.stringify(
|
|
16087
16436
|
[
|
|
16088
16437
|
"# Projects",
|
|
16089
16438
|
"",
|
|
@@ -16114,7 +16463,7 @@ function buildProjectsIndex(projectPages, schemaHash, metadata) {
|
|
|
16114
16463
|
}
|
|
16115
16464
|
function buildProjectIndex(input) {
|
|
16116
16465
|
const title = `Project: ${input.projectId}`;
|
|
16117
|
-
return
|
|
16466
|
+
return matter6.stringify(
|
|
16118
16467
|
[
|
|
16119
16468
|
`# ${title}`,
|
|
16120
16469
|
"",
|
|
@@ -16231,7 +16580,7 @@ function buildOutputPage(input) {
|
|
|
16231
16580
|
outputFormat: input.outputFormat,
|
|
16232
16581
|
outputAssets
|
|
16233
16582
|
},
|
|
16234
|
-
content:
|
|
16583
|
+
content: matter6.stringify(
|
|
16235
16584
|
(input.outputFormat === "slides" ? [
|
|
16236
16585
|
input.answer,
|
|
16237
16586
|
"",
|
|
@@ -16359,7 +16708,7 @@ function buildExploreHubPage(input) {
|
|
|
16359
16708
|
outputFormat: input.outputFormat,
|
|
16360
16709
|
outputAssets
|
|
16361
16710
|
},
|
|
16362
|
-
content:
|
|
16711
|
+
content: matter6.stringify(
|
|
16363
16712
|
(input.outputFormat === "slides" ? [
|
|
16364
16713
|
`# ${title}`,
|
|
16365
16714
|
"",
|
|
@@ -16625,12 +16974,12 @@ function buildOutputAssetManifest(input) {
|
|
|
16625
16974
|
// src/outputs.ts
|
|
16626
16975
|
import fs16 from "fs/promises";
|
|
16627
16976
|
import path20 from "path";
|
|
16628
|
-
import
|
|
16977
|
+
import matter8 from "gray-matter";
|
|
16629
16978
|
|
|
16630
16979
|
// src/pages.ts
|
|
16631
16980
|
import fs15 from "fs/promises";
|
|
16632
16981
|
import path19 from "path";
|
|
16633
|
-
import
|
|
16982
|
+
import matter7 from "gray-matter";
|
|
16634
16983
|
function normalizeStringArray(value) {
|
|
16635
16984
|
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
16636
16985
|
}
|
|
@@ -16711,7 +17060,7 @@ async function loadExistingManagedPageState(absolutePath, defaults = {}) {
|
|
|
16711
17060
|
};
|
|
16712
17061
|
}
|
|
16713
17062
|
const content = await fs15.readFile(absolutePath, "utf8");
|
|
16714
|
-
const parsed =
|
|
17063
|
+
const parsed = matter7(content);
|
|
16715
17064
|
return {
|
|
16716
17065
|
status: normalizePageStatus(parsed.data.status, defaults.status ?? "active"),
|
|
16717
17066
|
managedBy: normalizePageManager(parsed.data.managed_by, defaults.managedBy ?? "system"),
|
|
@@ -16745,7 +17094,7 @@ function inferPageKind(relativePath, explicitKind = void 0) {
|
|
|
16745
17094
|
return "index";
|
|
16746
17095
|
}
|
|
16747
17096
|
function parseStoredPage(relativePath, content, defaults = {}) {
|
|
16748
|
-
const parsed =
|
|
17097
|
+
const parsed = matter7(content);
|
|
16749
17098
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
16750
17099
|
const fallbackCreatedAt = defaults.createdAt ?? now;
|
|
16751
17100
|
const fallbackUpdatedAt = defaults.updatedAt ?? fallbackCreatedAt;
|
|
@@ -16800,7 +17149,7 @@ async function loadInsightPages(wikiDir) {
|
|
|
16800
17149
|
for (const absolutePath of files) {
|
|
16801
17150
|
const relativePath = toPosix(path19.relative(wikiDir, absolutePath));
|
|
16802
17151
|
const content = await fs15.readFile(absolutePath, "utf8");
|
|
16803
|
-
const parsed =
|
|
17152
|
+
const parsed = matter7(content);
|
|
16804
17153
|
const stats = await fs15.stat(absolutePath);
|
|
16805
17154
|
const title = typeof parsed.data.title === "string" ? parsed.data.title : path19.basename(absolutePath, ".md");
|
|
16806
17155
|
const sourceIds = normalizeStringArray(parsed.data.source_ids);
|
|
@@ -16901,7 +17250,7 @@ async function loadSavedOutputPages(wikiDir) {
|
|
|
16901
17250
|
const relativePath = path20.posix.join(current.relativeDir, entry.name);
|
|
16902
17251
|
const absolutePath = path20.join(current.absoluteDir, entry.name);
|
|
16903
17252
|
const content = await fs16.readFile(absolutePath, "utf8");
|
|
16904
|
-
const parsed =
|
|
17253
|
+
const parsed = matter8(content);
|
|
16905
17254
|
const slug = relativePath.replace(/^outputs\//, "").replace(/\.md$/, "");
|
|
16906
17255
|
const title = typeof parsed.data.title === "string" ? parsed.data.title : path20.basename(slug);
|
|
16907
17256
|
const pageId = typeof parsed.data.page_id === "string" ? parsed.data.page_id : `output:${slug}`;
|
|
@@ -16955,7 +17304,7 @@ async function loadSavedOutputPages(wikiDir) {
|
|
|
16955
17304
|
// src/search.ts
|
|
16956
17305
|
import fs17 from "fs/promises";
|
|
16957
17306
|
import path21 from "path";
|
|
16958
|
-
import
|
|
17307
|
+
import matter9 from "gray-matter";
|
|
16959
17308
|
function warningMessage(warning) {
|
|
16960
17309
|
return warning instanceof Error ? warning.message : String(warning);
|
|
16961
17310
|
}
|
|
@@ -17043,7 +17392,7 @@ async function rebuildSearchIndex(dbPath, pages, wikiDir) {
|
|
|
17043
17392
|
for (const page of pages) {
|
|
17044
17393
|
const absolutePath = path21.join(wikiDir, page.path);
|
|
17045
17394
|
const content = await fs17.readFile(absolutePath, "utf8");
|
|
17046
|
-
const parsed =
|
|
17395
|
+
const parsed = matter9(content);
|
|
17047
17396
|
let body = parsed.content;
|
|
17048
17397
|
const primarySourceId = Array.isArray(parsed.data.source_ids) && typeof parsed.data.source_ids[0] === "string" ? parsed.data.source_ids[0] : page.sourceIds[0];
|
|
17049
17398
|
if ((page.kind === "source" || page.kind === "module") && primarySourceId) {
|
|
@@ -17454,7 +17803,7 @@ async function resolveImageGenerationProvider(rootDir) {
|
|
|
17454
17803
|
if (!providerConfig) {
|
|
17455
17804
|
throw new Error(`No provider configured with id "${preferredProviderId}" for task "imageProvider".`);
|
|
17456
17805
|
}
|
|
17457
|
-
const { createProvider: createProvider2 } = await import("./registry-
|
|
17806
|
+
const { createProvider: createProvider2 } = await import("./registry-SYCRRA65.js");
|
|
17458
17807
|
return createProvider2(preferredProviderId, providerConfig, rootDir);
|
|
17459
17808
|
}
|
|
17460
17809
|
async function generateOutputArtifacts(rootDir, input) {
|
|
@@ -17973,7 +18322,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
17973
18322
|
{
|
|
17974
18323
|
relativePath: "dashboards/index.md",
|
|
17975
18324
|
title: "Dashboards",
|
|
17976
|
-
content: (metadata) =>
|
|
18325
|
+
content: (metadata) => matter10.stringify(
|
|
17977
18326
|
[
|
|
17978
18327
|
"# Dashboards",
|
|
17979
18328
|
"",
|
|
@@ -18025,7 +18374,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
18025
18374
|
{
|
|
18026
18375
|
relativePath: "dashboards/recent-sources.md",
|
|
18027
18376
|
title: "Recent Sources",
|
|
18028
|
-
content: (metadata) =>
|
|
18377
|
+
content: (metadata) => matter10.stringify(
|
|
18029
18378
|
[
|
|
18030
18379
|
"# Recent Sources",
|
|
18031
18380
|
"",
|
|
@@ -18068,7 +18417,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
18068
18417
|
{
|
|
18069
18418
|
relativePath: "dashboards/reading-log.md",
|
|
18070
18419
|
title: "Reading Log",
|
|
18071
|
-
content: (metadata) =>
|
|
18420
|
+
content: (metadata) => matter10.stringify(
|
|
18072
18421
|
[
|
|
18073
18422
|
"# Reading Log",
|
|
18074
18423
|
"",
|
|
@@ -18128,7 +18477,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
18128
18477
|
{
|
|
18129
18478
|
relativePath: "dashboards/timeline.md",
|
|
18130
18479
|
title: "Timeline",
|
|
18131
|
-
content: (metadata) =>
|
|
18480
|
+
content: (metadata) => matter10.stringify(
|
|
18132
18481
|
[
|
|
18133
18482
|
"# Timeline",
|
|
18134
18483
|
"",
|
|
@@ -18174,7 +18523,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
18174
18523
|
{
|
|
18175
18524
|
relativePath: "dashboards/source-sessions.md",
|
|
18176
18525
|
title: "Source Sessions",
|
|
18177
|
-
content: (metadata) =>
|
|
18526
|
+
content: (metadata) => matter10.stringify(
|
|
18178
18527
|
[
|
|
18179
18528
|
"# Source Sessions",
|
|
18180
18529
|
"",
|
|
@@ -18231,7 +18580,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
18231
18580
|
{
|
|
18232
18581
|
relativePath: "dashboards/source-guides.md",
|
|
18233
18582
|
title: "Source Guides",
|
|
18234
|
-
content: (metadata) =>
|
|
18583
|
+
content: (metadata) => matter10.stringify(
|
|
18235
18584
|
[
|
|
18236
18585
|
"# Source Guides",
|
|
18237
18586
|
"",
|
|
@@ -18284,7 +18633,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
18284
18633
|
{
|
|
18285
18634
|
relativePath: "dashboards/research-map.md",
|
|
18286
18635
|
title: "Research Map",
|
|
18287
|
-
content: (metadata) =>
|
|
18636
|
+
content: (metadata) => matter10.stringify(
|
|
18288
18637
|
[
|
|
18289
18638
|
"# Research Map",
|
|
18290
18639
|
"",
|
|
@@ -18348,7 +18697,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
18348
18697
|
{
|
|
18349
18698
|
relativePath: "dashboards/contradictions.md",
|
|
18350
18699
|
title: "Contradictions",
|
|
18351
|
-
content: (metadata) =>
|
|
18700
|
+
content: (metadata) => matter10.stringify(
|
|
18352
18701
|
[
|
|
18353
18702
|
"# Contradictions",
|
|
18354
18703
|
"",
|
|
@@ -18407,7 +18756,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
18407
18756
|
{
|
|
18408
18757
|
relativePath: "dashboards/open-questions.md",
|
|
18409
18758
|
title: "Open Questions",
|
|
18410
|
-
content: (metadata) =>
|
|
18759
|
+
content: (metadata) => matter10.stringify(
|
|
18411
18760
|
[
|
|
18412
18761
|
"# Open Questions",
|
|
18413
18762
|
"",
|
|
@@ -18483,7 +18832,12 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
18483
18832
|
function indexCompiledFrom(pages) {
|
|
18484
18833
|
return uniqueStrings3(pages.flatMap((page) => page.sourceIds));
|
|
18485
18834
|
}
|
|
18486
|
-
function
|
|
18835
|
+
function autoResolution(nodeCount, edgeCount) {
|
|
18836
|
+
if (nodeCount <= 20) return 0.5;
|
|
18837
|
+
if (edgeCount / Math.max(1, nodeCount) < 2) return 0.8;
|
|
18838
|
+
return 1;
|
|
18839
|
+
}
|
|
18840
|
+
function deriveGraphMetrics(nodes, edges, options) {
|
|
18487
18841
|
const adjacency = /* @__PURE__ */ new Map();
|
|
18488
18842
|
const connect = (left, right) => {
|
|
18489
18843
|
if (!adjacency.has(left)) {
|
|
@@ -18520,7 +18874,8 @@ function deriveGraphMetrics(nodes, edges) {
|
|
|
18520
18874
|
}
|
|
18521
18875
|
}
|
|
18522
18876
|
}
|
|
18523
|
-
const
|
|
18877
|
+
const effectiveResolution = options?.resolution ?? autoResolution(louvainGraph.order, louvainGraph.size);
|
|
18878
|
+
const louvainMapping = louvainGraph.size > 0 ? louvain(louvainGraph, { resolution: effectiveResolution }) : {};
|
|
18524
18879
|
const groupByCommunity = /* @__PURE__ */ new Map();
|
|
18525
18880
|
let nextIsolated = -1;
|
|
18526
18881
|
for (const node of nonSourceNodes) {
|
|
@@ -18666,7 +19021,7 @@ function detectContradictions(analyses) {
|
|
|
18666
19021
|
}
|
|
18667
19022
|
return contradictions;
|
|
18668
19023
|
}
|
|
18669
|
-
function buildGraph(manifests, analyses, pages, sourceProjects, _codeIndex) {
|
|
19024
|
+
function buildGraph(manifests, analyses, pages, sourceProjects, _codeIndex, options) {
|
|
18670
19025
|
const manifestsById = new Map(manifests.map((manifest) => [manifest.sourceId, manifest]));
|
|
18671
19026
|
const goPackageSymbolLookups = buildGoPackageSymbolLookups(analyses, manifestsById);
|
|
18672
19027
|
const analysesBySourceId = new Map(analyses.map((analysis) => [analysis.sourceId, analysis]));
|
|
@@ -19026,7 +19381,7 @@ function buildGraph(manifests, analyses, pages, sourceProjects, _codeIndex) {
|
|
|
19026
19381
|
manifests,
|
|
19027
19382
|
analyses
|
|
19028
19383
|
);
|
|
19029
|
-
const metrics = deriveGraphMetrics(graphNodes, enriched.edges);
|
|
19384
|
+
const metrics = deriveGraphMetrics(graphNodes, enriched.edges, { resolution: options?.communityResolution });
|
|
19030
19385
|
return {
|
|
19031
19386
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19032
19387
|
nodes: metrics.nodes,
|
|
@@ -19493,7 +19848,9 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
19493
19848
|
}
|
|
19494
19849
|
const compiledPages = records.map((record) => record.page);
|
|
19495
19850
|
const basePages = [...compiledPages, ...input.outputPages, ...input.insightPages];
|
|
19496
|
-
const structuralGraph = buildGraph(input.manifests, input.analyses, basePages, input.sourceProjects, input.codeIndex
|
|
19851
|
+
const structuralGraph = buildGraph(input.manifests, input.analyses, basePages, input.sourceProjects, input.codeIndex, {
|
|
19852
|
+
communityResolution: config.graph?.communityResolution
|
|
19853
|
+
});
|
|
19497
19854
|
const contradictions = detectContradictions(input.analyses);
|
|
19498
19855
|
for (const contradiction of contradictions) {
|
|
19499
19856
|
const edgeId = `contradiction:${contradiction.sourceIdA}->${contradiction.sourceIdB}`;
|
|
@@ -19515,7 +19872,9 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
19515
19872
|
const edges = uniqueBy([...structuralGraph.edges, ...embeddingEdges], (edge) => edge.id).sort(
|
|
19516
19873
|
(left, right) => left.id.localeCompare(right.id)
|
|
19517
19874
|
);
|
|
19518
|
-
const metrics = deriveGraphMetrics(resetGraphNodeMetrics(structuralGraph.nodes), edges
|
|
19875
|
+
const metrics = deriveGraphMetrics(resetGraphNodeMetrics(structuralGraph.nodes), edges, {
|
|
19876
|
+
resolution: config.graph?.communityResolution
|
|
19877
|
+
});
|
|
19519
19878
|
return {
|
|
19520
19879
|
...structuralGraph,
|
|
19521
19880
|
nodes: metrics.nodes,
|
|
@@ -20086,7 +20445,7 @@ async function executeQuery(rootDir, question, format) {
|
|
|
20086
20445
|
const absolutePath = path23.join(paths.wikiDir, result.path);
|
|
20087
20446
|
try {
|
|
20088
20447
|
const content = await fs19.readFile(absolutePath, "utf8");
|
|
20089
|
-
const parsed =
|
|
20448
|
+
const parsed = matter10(content);
|
|
20090
20449
|
return `# ${result.title}
|
|
20091
20450
|
${truncate(normalizeWhitespace(parsed.content), 1200)}`;
|
|
20092
20451
|
} catch {
|
|
@@ -20299,8 +20658,8 @@ function computeChangeSummary(current, staged, changeType) {
|
|
|
20299
20658
|
if (changeType === "delete") return "Removed page";
|
|
20300
20659
|
if (changeType === "promote") return "Promoted from candidate";
|
|
20301
20660
|
if (!current || !staged) return "Updated page";
|
|
20302
|
-
const currentParsed =
|
|
20303
|
-
const stagedParsed =
|
|
20661
|
+
const currentParsed = matter10(current);
|
|
20662
|
+
const stagedParsed = matter10(staged);
|
|
20304
20663
|
const changes = [];
|
|
20305
20664
|
const currentTags = currentParsed.data.tags ?? [];
|
|
20306
20665
|
const stagedTags = stagedParsed.data.tags ?? [];
|
|
@@ -20501,9 +20860,9 @@ async function promoteCandidate(rootDir, target) {
|
|
|
20501
20860
|
const graph = await readJsonFile(paths.graphPath);
|
|
20502
20861
|
const candidate = resolveCandidateTarget(graph?.pages ?? [], target);
|
|
20503
20862
|
const raw = await fs19.readFile(path23.join(paths.wikiDir, candidate.path), "utf8");
|
|
20504
|
-
const parsed =
|
|
20863
|
+
const parsed = matter10(raw);
|
|
20505
20864
|
const nextUpdatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
20506
|
-
const nextContent =
|
|
20865
|
+
const nextContent = matter10.stringify(parsed.content, {
|
|
20507
20866
|
...parsed.data,
|
|
20508
20867
|
status: "active",
|
|
20509
20868
|
updated_at: nextUpdatedAt,
|
|
@@ -20654,7 +21013,7 @@ async function initVault(rootDir, options = {}) {
|
|
|
20654
21013
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
20655
21014
|
await writeFileIfChanged(
|
|
20656
21015
|
insightsIndexPath,
|
|
20657
|
-
|
|
21016
|
+
matter10.stringify(
|
|
20658
21017
|
(isResearchProfile ? [
|
|
20659
21018
|
"# Insights",
|
|
20660
21019
|
"",
|
|
@@ -20701,7 +21060,7 @@ async function initVault(rootDir, options = {}) {
|
|
|
20701
21060
|
);
|
|
20702
21061
|
await writeFileIfChanged(
|
|
20703
21062
|
path23.join(paths.wikiDir, "projects", "index.md"),
|
|
20704
|
-
|
|
21063
|
+
matter10.stringify(["# Projects", "", "- Run `swarmvault compile` to build project rollups.", ""].join("\n"), {
|
|
20705
21064
|
page_id: "projects:index",
|
|
20706
21065
|
kind: "index",
|
|
20707
21066
|
title: "Projects",
|
|
@@ -20724,7 +21083,7 @@ async function initVault(rootDir, options = {}) {
|
|
|
20724
21083
|
);
|
|
20725
21084
|
await writeFileIfChanged(
|
|
20726
21085
|
path23.join(paths.wikiDir, "candidates", "index.md"),
|
|
20727
|
-
|
|
21086
|
+
matter10.stringify(["# Candidates", "", "- Run `swarmvault compile` to stage candidate pages.", ""].join("\n"), {
|
|
20728
21087
|
page_id: "candidates:index",
|
|
20729
21088
|
kind: "index",
|
|
20730
21089
|
title: "Candidates",
|
|
@@ -20751,7 +21110,7 @@ async function initVault(rootDir, options = {}) {
|
|
|
20751
21110
|
if (isResearchProfile) {
|
|
20752
21111
|
await writeFileIfChanged(
|
|
20753
21112
|
path23.join(paths.wikiDir, "insights", "research-playbook.md"),
|
|
20754
|
-
|
|
21113
|
+
matter10.stringify(
|
|
20755
21114
|
[
|
|
20756
21115
|
`# ${requestedProfile === "personal-research" ? "Personal Research Playbook" : "Research Playbook"}`,
|
|
20757
21116
|
"",
|
|
@@ -21536,7 +21895,7 @@ async function benchmarkVault(rootDir, options = {}) {
|
|
|
21536
21895
|
if (!await fileExists(absolutePath)) {
|
|
21537
21896
|
continue;
|
|
21538
21897
|
}
|
|
21539
|
-
const parsed =
|
|
21898
|
+
const parsed = matter10(await fs19.readFile(absolutePath, "utf8"));
|
|
21540
21899
|
pageContentsById.set(page.id, parsed.content);
|
|
21541
21900
|
}
|
|
21542
21901
|
const configuredQuestions = (config.benchmark?.questions ?? []).map((question) => normalizeWhitespace(question)).filter(Boolean);
|
|
@@ -21620,7 +21979,7 @@ async function readPage(rootDir, relativePath) {
|
|
|
21620
21979
|
return null;
|
|
21621
21980
|
}
|
|
21622
21981
|
const raw = await fs19.readFile(absolutePath, "utf8");
|
|
21623
|
-
const parsed =
|
|
21982
|
+
const parsed = matter10(raw);
|
|
21624
21983
|
return {
|
|
21625
21984
|
path: relativePath,
|
|
21626
21985
|
title: typeof parsed.data.title === "string" ? parsed.data.title : path23.basename(relativePath, path23.extname(relativePath)),
|
|
@@ -21835,7 +22194,7 @@ async function bootstrapDemo(rootDir, input) {
|
|
|
21835
22194
|
}
|
|
21836
22195
|
|
|
21837
22196
|
// src/mcp.ts
|
|
21838
|
-
var SERVER_VERSION = "0.7.
|
|
22197
|
+
var SERVER_VERSION = "0.7.26";
|
|
21839
22198
|
async function createMcpServer(rootDir) {
|
|
21840
22199
|
const server = new McpServer({
|
|
21841
22200
|
name: "swarmvault",
|
|
@@ -22520,7 +22879,7 @@ async function serveSchedules(rootDir, pollMs = 3e4) {
|
|
|
22520
22879
|
import { spawn as spawn2 } from "child_process";
|
|
22521
22880
|
import fs22 from "fs/promises";
|
|
22522
22881
|
import path26 from "path";
|
|
22523
|
-
import
|
|
22882
|
+
import matter11 from "gray-matter";
|
|
22524
22883
|
import { JSDOM as JSDOM3 } from "jsdom";
|
|
22525
22884
|
var DEFAULT_CRAWL_MAX_PAGES = 12;
|
|
22526
22885
|
var DEFAULT_CRAWL_MAX_DEPTH = 2;
|
|
@@ -23863,7 +24222,7 @@ async function buildGuidedUpdatePages(rootDir, scope, session) {
|
|
|
23863
24222
|
const relativePath = useCanonicalTargets && targetPage ? targetPage.path : targetPage ? insightRelativePathForTarget(targetPage, scope) : `insights/topics/${slugify(scope.title)}.md`;
|
|
23864
24223
|
const absolutePath = path26.join(paths.wikiDir, relativePath);
|
|
23865
24224
|
const existingContent = await fileExists(absolutePath) ? await fs22.readFile(absolutePath, "utf8") : "";
|
|
23866
|
-
const parsed = existingContent ?
|
|
24225
|
+
const parsed = existingContent ? matter11(existingContent) : { data: {}, content: "" };
|
|
23867
24226
|
const existingData = parsed.data;
|
|
23868
24227
|
const existingSourceIds = Array.isArray(existingData.source_ids) ? existingData.source_ids.filter((value) => typeof value === "string") : [];
|
|
23869
24228
|
const existingProjectIds = Array.isArray(existingData.project_ids) ? existingData.project_ids.filter((value) => typeof value === "string") : [];
|
|
@@ -23924,7 +24283,7 @@ async function buildGuidedUpdatePages(rootDir, scope, session) {
|
|
|
23924
24283
|
""
|
|
23925
24284
|
].join("\n");
|
|
23926
24285
|
const nextBody = replaceMarkedSection(baseBody, scope.id, updateBlock);
|
|
23927
|
-
const content =
|
|
24286
|
+
const content = matter11.stringify(
|
|
23928
24287
|
`${nextBody.trimEnd()}
|
|
23929
24288
|
`,
|
|
23930
24289
|
JSON.parse(
|
|
@@ -24310,7 +24669,7 @@ import fs23 from "fs/promises";
|
|
|
24310
24669
|
import http from "http";
|
|
24311
24670
|
import path28 from "path";
|
|
24312
24671
|
import { promisify as promisify2 } from "util";
|
|
24313
|
-
import
|
|
24672
|
+
import matter12 from "gray-matter";
|
|
24314
24673
|
import mime2 from "mime-types";
|
|
24315
24674
|
|
|
24316
24675
|
// src/graph-presentation.ts
|
|
@@ -24942,7 +25301,7 @@ async function readViewerPage(rootDir, relativePath) {
|
|
|
24942
25301
|
return null;
|
|
24943
25302
|
}
|
|
24944
25303
|
const raw = await fs23.readFile(absolutePath, "utf8");
|
|
24945
|
-
const parsed =
|
|
25304
|
+
const parsed = matter12(raw);
|
|
24946
25305
|
return {
|
|
24947
25306
|
path: relativePath,
|
|
24948
25307
|
title: typeof parsed.data.title === "string" ? parsed.data.title : path28.basename(relativePath, path28.extname(relativePath)),
|