@swarmvaultai/engine 0.6.0 → 0.6.1
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/chunk-OK5752AP.js +1325 -0
- package/dist/index.d.ts +15 -5
- package/dist/index.js +423 -204
- package/dist/registry-TYROWPR5.js +12 -0
- package/package.json +7 -7
- package/LICENSE +0 -21
package/dist/index.js
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
uniqueBy,
|
|
22
22
|
writeFileIfChanged,
|
|
23
23
|
writeJsonFile
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-OK5752AP.js";
|
|
25
25
|
|
|
26
26
|
// src/agents.ts
|
|
27
27
|
import crypto from "crypto";
|
|
@@ -10579,6 +10579,43 @@ import matter5 from "gray-matter";
|
|
|
10579
10579
|
function uniqueStrings2(values) {
|
|
10580
10580
|
return uniqueBy(values.filter(Boolean), (value) => value);
|
|
10581
10581
|
}
|
|
10582
|
+
var GUIDED_SOURCE_MARKER_PREFIX = "<!-- swarmvault-guided-source:";
|
|
10583
|
+
var GUIDED_SOURCE_START_SUFFIX = ":start -->";
|
|
10584
|
+
var GUIDED_SOURCE_END_SUFFIX = ":end -->";
|
|
10585
|
+
function extractGuidedSourceBlocks(content) {
|
|
10586
|
+
if (!content) {
|
|
10587
|
+
return [];
|
|
10588
|
+
}
|
|
10589
|
+
const blocks = [];
|
|
10590
|
+
let cursor = 0;
|
|
10591
|
+
while (cursor < content.length) {
|
|
10592
|
+
const startIndex = content.indexOf(GUIDED_SOURCE_MARKER_PREFIX, cursor);
|
|
10593
|
+
if (startIndex === -1) {
|
|
10594
|
+
break;
|
|
10595
|
+
}
|
|
10596
|
+
const scopeEndIndex = content.indexOf(GUIDED_SOURCE_START_SUFFIX, startIndex);
|
|
10597
|
+
if (scopeEndIndex === -1) {
|
|
10598
|
+
break;
|
|
10599
|
+
}
|
|
10600
|
+
const scopeId = content.slice(startIndex + GUIDED_SOURCE_MARKER_PREFIX.length, scopeEndIndex);
|
|
10601
|
+
const endMarker = `${GUIDED_SOURCE_MARKER_PREFIX}${scopeId}${GUIDED_SOURCE_END_SUFFIX}`;
|
|
10602
|
+
const endIndex = content.indexOf(endMarker, scopeEndIndex);
|
|
10603
|
+
if (endIndex === -1) {
|
|
10604
|
+
break;
|
|
10605
|
+
}
|
|
10606
|
+
const blockEnd = endIndex + endMarker.length;
|
|
10607
|
+
blocks.push(content.slice(startIndex, blockEnd).trim());
|
|
10608
|
+
cursor = blockEnd;
|
|
10609
|
+
}
|
|
10610
|
+
return uniqueStrings2(blocks);
|
|
10611
|
+
}
|
|
10612
|
+
function appendGuidedSourceBlocks(body, existingContent) {
|
|
10613
|
+
const blocks = extractGuidedSourceBlocks(existingContent);
|
|
10614
|
+
if (!blocks.length) {
|
|
10615
|
+
return body;
|
|
10616
|
+
}
|
|
10617
|
+
return [body.trimEnd(), "", "## Guided Session Notes", "", ...blocks, ""].join("\n");
|
|
10618
|
+
}
|
|
10582
10619
|
function safeFrontmatter(value) {
|
|
10583
10620
|
return JSON.parse(JSON.stringify(value));
|
|
10584
10621
|
}
|
|
@@ -10667,7 +10704,7 @@ function detailList(manifest, key) {
|
|
|
10667
10704
|
const items = value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
10668
10705
|
return items.length ? items : void 0;
|
|
10669
10706
|
}
|
|
10670
|
-
function buildSourcePage(manifest, analysis, schemaHash, metadata, relatedOutputs = [], modulePage, decorations) {
|
|
10707
|
+
function buildSourcePage(manifest, analysis, schemaHash, metadata, relatedOutputs = [], modulePage, decorations, existingContent) {
|
|
10671
10708
|
const relativePath = pagePathFor("source", manifest.sourceId);
|
|
10672
10709
|
const pageId = `source:${manifest.sourceId}`;
|
|
10673
10710
|
const { sourceHashes, sourceSemanticHashes } = sourceHashesForManifest(manifest);
|
|
@@ -10709,61 +10746,64 @@ function buildSourcePage(manifest, analysis, schemaHash, metadata, relatedOutput
|
|
|
10709
10746
|
schema_hash: schemaHash,
|
|
10710
10747
|
...sourceHashFrontmatter(sourceHashes, sourceSemanticHashes)
|
|
10711
10748
|
};
|
|
10712
|
-
const body =
|
|
10713
|
-
|
|
10714
|
-
|
|
10715
|
-
`Source ID: \`${manifest.sourceId}\``,
|
|
10716
|
-
`Source Kind: \`${manifest.sourceKind}\``,
|
|
10717
|
-
manifest.url ? `Source URL: ${manifest.url}` : `Source Path: \`${manifest.originalPath ?? manifest.storedPath}\``,
|
|
10718
|
-
...manifest.sourceType ? [`Source Type: \`${manifest.sourceType}\``, ""] : [""],
|
|
10719
|
-
...manifest.sourceClass ? [`Source Class: \`${manifest.sourceClass}\``, ""] : [],
|
|
10720
|
-
...manifest.sourceGroupTitle ? [`Source Group: ${manifest.sourceGroupTitle}`] : [],
|
|
10721
|
-
...manifest.partTitle ? [`Part: ${manifest.partIndex ?? "?"}/${manifest.partCount ?? "?"} - ${manifest.partTitle}`] : [],
|
|
10722
|
-
...manifest.details && Object.keys(manifest.details).length ? [
|
|
10749
|
+
const body = appendGuidedSourceBlocks(
|
|
10750
|
+
[
|
|
10751
|
+
`# ${analysis.title}`,
|
|
10723
10752
|
"",
|
|
10724
|
-
|
|
10753
|
+
`Source ID: \`${manifest.sourceId}\``,
|
|
10754
|
+
`Source Kind: \`${manifest.sourceKind}\``,
|
|
10755
|
+
manifest.url ? `Source URL: ${manifest.url}` : `Source Path: \`${manifest.originalPath ?? manifest.storedPath}\``,
|
|
10756
|
+
...manifest.sourceType ? [`Source Type: \`${manifest.sourceType}\``, ""] : [""],
|
|
10757
|
+
...manifest.sourceClass ? [`Source Class: \`${manifest.sourceClass}\``, ""] : [],
|
|
10758
|
+
...manifest.sourceGroupTitle ? [`Source Group: ${manifest.sourceGroupTitle}`] : [],
|
|
10759
|
+
...manifest.partTitle ? [`Part: ${manifest.partIndex ?? "?"}/${manifest.partCount ?? "?"} - ${manifest.partTitle}`] : [],
|
|
10760
|
+
...manifest.details && Object.keys(manifest.details).length ? [
|
|
10761
|
+
"",
|
|
10762
|
+
"## Source Details",
|
|
10763
|
+
"",
|
|
10764
|
+
...Object.entries(manifest.details).map(([key, value]) => `- ${key.replace(/_/g, " ")}: ${value}`),
|
|
10765
|
+
""
|
|
10766
|
+
] : [],
|
|
10725
10767
|
"",
|
|
10726
|
-
|
|
10727
|
-
""
|
|
10728
|
-
|
|
10729
|
-
|
|
10730
|
-
|
|
10731
|
-
|
|
10732
|
-
|
|
10733
|
-
|
|
10734
|
-
|
|
10735
|
-
|
|
10768
|
+
"## Summary",
|
|
10769
|
+
"",
|
|
10770
|
+
analysis.summary,
|
|
10771
|
+
"",
|
|
10772
|
+
...analysis.code ? [
|
|
10773
|
+
"## Code Module",
|
|
10774
|
+
"",
|
|
10775
|
+
`- Language: \`${analysis.code.language}\``,
|
|
10776
|
+
modulePage ? `- Module Page: [[${modulePage.path.replace(/\.md$/, "")}|${modulePage.title}]]` : "- Module Page: Not generated.",
|
|
10777
|
+
`- Exports: ${analysis.code.exports.length ? analysis.code.exports.join(", ") : "None detected."}`,
|
|
10778
|
+
`- Symbols: ${analysis.code.symbols.length ? analysis.code.symbols.map((symbol) => symbol.name).join(", ") : "None detected."}`,
|
|
10779
|
+
analysis.code.diagnostics.length ? `- Diagnostics: ${analysis.code.diagnostics.length}` : "- Diagnostics: None.",
|
|
10780
|
+
""
|
|
10781
|
+
] : [],
|
|
10782
|
+
"## Concepts",
|
|
10783
|
+
"",
|
|
10784
|
+
...analysis.concepts.length ? analysis.concepts.map(
|
|
10785
|
+
(item) => `- [[${pagePathFor("concept", slugify(item.name)).replace(/\.md$/, "")}|${item.name}]]: ${item.description}`
|
|
10786
|
+
) : ["- None detected."],
|
|
10787
|
+
"",
|
|
10788
|
+
"## Entities",
|
|
10789
|
+
"",
|
|
10790
|
+
...analysis.entities.length ? analysis.entities.map(
|
|
10791
|
+
(item) => `- [[${pagePathFor("entity", slugify(item.name)).replace(/\.md$/, "")}|${item.name}]]: ${item.description}`
|
|
10792
|
+
) : ["- None detected."],
|
|
10793
|
+
"",
|
|
10794
|
+
"## Claims",
|
|
10736
10795
|
"",
|
|
10737
|
-
`-
|
|
10738
|
-
|
|
10739
|
-
|
|
10740
|
-
|
|
10741
|
-
analysis.
|
|
10796
|
+
...analysis.claims.length ? analysis.claims.map((claim) => `- ${claim.text} [source:${claim.citation}]`) : ["- No claims extracted."],
|
|
10797
|
+
"",
|
|
10798
|
+
"## Questions",
|
|
10799
|
+
"",
|
|
10800
|
+
...analysis.questions.length ? analysis.questions.map((question) => `- ${question}`) : ["- No follow-up questions yet."],
|
|
10801
|
+
"",
|
|
10802
|
+
...relatedOutputsSection(relatedOutputs),
|
|
10742
10803
|
""
|
|
10743
|
-
]
|
|
10744
|
-
|
|
10745
|
-
|
|
10746
|
-
...analysis.concepts.length ? analysis.concepts.map(
|
|
10747
|
-
(item) => `- [[${pagePathFor("concept", slugify(item.name)).replace(/\.md$/, "")}|${item.name}]]: ${item.description}`
|
|
10748
|
-
) : ["- None detected."],
|
|
10749
|
-
"",
|
|
10750
|
-
"## Entities",
|
|
10751
|
-
"",
|
|
10752
|
-
...analysis.entities.length ? analysis.entities.map(
|
|
10753
|
-
(item) => `- [[${pagePathFor("entity", slugify(item.name)).replace(/\.md$/, "")}|${item.name}]]: ${item.description}`
|
|
10754
|
-
) : ["- None detected."],
|
|
10755
|
-
"",
|
|
10756
|
-
"## Claims",
|
|
10757
|
-
"",
|
|
10758
|
-
...analysis.claims.length ? analysis.claims.map((claim) => `- ${claim.text} [source:${claim.citation}]`) : ["- No claims extracted."],
|
|
10759
|
-
"",
|
|
10760
|
-
"## Questions",
|
|
10761
|
-
"",
|
|
10762
|
-
...analysis.questions.length ? analysis.questions.map((question) => `- ${question}`) : ["- No follow-up questions yet."],
|
|
10763
|
-
"",
|
|
10764
|
-
...relatedOutputsSection(relatedOutputs),
|
|
10765
|
-
""
|
|
10766
|
-
].join("\n");
|
|
10804
|
+
].join("\n"),
|
|
10805
|
+
existingContent
|
|
10806
|
+
);
|
|
10767
10807
|
return {
|
|
10768
10808
|
page: {
|
|
10769
10809
|
id: pageId,
|
|
@@ -10943,7 +10983,7 @@ function buildModulePage(input) {
|
|
|
10943
10983
|
content: matter5.stringify(body, frontmatter)
|
|
10944
10984
|
};
|
|
10945
10985
|
}
|
|
10946
|
-
function buildAggregatePage(kind, name, descriptions, sourceAnalyses, sourceHashes, sourceSemanticHashes, schemaHash, metadata, relativePath, relatedOutputs = [], decorations) {
|
|
10986
|
+
function buildAggregatePage(kind, name, descriptions, sourceAnalyses, sourceHashes, sourceSemanticHashes, schemaHash, metadata, relativePath, relatedOutputs = [], decorations, existingContent) {
|
|
10947
10987
|
const slug = slugify(name);
|
|
10948
10988
|
const pageId = `${kind}:${slug}`;
|
|
10949
10989
|
const sourceIds = sourceAnalyses.map((item) => item.sourceId);
|
|
@@ -10969,26 +11009,29 @@ function buildAggregatePage(kind, name, descriptions, sourceAnalyses, sourceHash
|
|
|
10969
11009
|
schema_hash: schemaHash,
|
|
10970
11010
|
...sourceHashFrontmatter(sourceHashes, sourceSemanticHashes)
|
|
10971
11011
|
};
|
|
10972
|
-
const body =
|
|
10973
|
-
|
|
10974
|
-
|
|
10975
|
-
|
|
10976
|
-
|
|
10977
|
-
|
|
10978
|
-
|
|
10979
|
-
|
|
10980
|
-
|
|
10981
|
-
|
|
10982
|
-
|
|
10983
|
-
|
|
10984
|
-
|
|
10985
|
-
|
|
10986
|
-
|
|
10987
|
-
|
|
10988
|
-
|
|
10989
|
-
|
|
10990
|
-
|
|
10991
|
-
|
|
11012
|
+
const body = appendGuidedSourceBlocks(
|
|
11013
|
+
[
|
|
11014
|
+
`# ${name}`,
|
|
11015
|
+
"",
|
|
11016
|
+
"## Summary",
|
|
11017
|
+
"",
|
|
11018
|
+
summary,
|
|
11019
|
+
"",
|
|
11020
|
+
"## Seen In",
|
|
11021
|
+
"",
|
|
11022
|
+
...sourceAnalyses.map((item) => `- [[${pagePathFor("source", item.sourceId).replace(/\.md$/, "")}|${item.title}]]`),
|
|
11023
|
+
"",
|
|
11024
|
+
"## Source Claims",
|
|
11025
|
+
"",
|
|
11026
|
+
...sourceAnalyses.flatMap(
|
|
11027
|
+
(item) => item.claims.filter((claim) => claim.text.toLowerCase().includes(name.toLowerCase())).map((claim) => `- ${claim.text} [source:${claim.citation}]`)
|
|
11028
|
+
),
|
|
11029
|
+
"",
|
|
11030
|
+
...relatedOutputsSection(relatedOutputs),
|
|
11031
|
+
""
|
|
11032
|
+
].join("\n"),
|
|
11033
|
+
existingContent
|
|
11034
|
+
);
|
|
10992
11035
|
return {
|
|
10993
11036
|
page: {
|
|
10994
11037
|
id: pageId,
|
|
@@ -11744,7 +11787,8 @@ function buildOutputPage(input) {
|
|
|
11744
11787
|
question: input.question,
|
|
11745
11788
|
output_format: input.outputFormat,
|
|
11746
11789
|
output_assets: outputAssets,
|
|
11747
|
-
...input.outputFormat === "slides" ? { marp: true } : {}
|
|
11790
|
+
...input.outputFormat === "slides" ? { marp: true } : {},
|
|
11791
|
+
...input.frontmatter ?? {}
|
|
11748
11792
|
};
|
|
11749
11793
|
return {
|
|
11750
11794
|
page: {
|
|
@@ -11832,7 +11876,7 @@ function buildOutputPage(input) {
|
|
|
11832
11876
|
...input.citations.map((citation) => `- [source:${citation}]`),
|
|
11833
11877
|
""
|
|
11834
11878
|
]).join("\n"),
|
|
11835
|
-
frontmatter
|
|
11879
|
+
safeFrontmatter(frontmatter)
|
|
11836
11880
|
)
|
|
11837
11881
|
};
|
|
11838
11882
|
}
|
|
@@ -12937,7 +12981,7 @@ async function resolveImageGenerationProvider(rootDir) {
|
|
|
12937
12981
|
if (!providerConfig) {
|
|
12938
12982
|
throw new Error(`No provider configured with id "${preferredProviderId}" for task "imageProvider".`);
|
|
12939
12983
|
}
|
|
12940
|
-
const { createProvider: createProvider2 } = await import("./registry-
|
|
12984
|
+
const { createProvider: createProvider2 } = await import("./registry-TYROWPR5.js");
|
|
12941
12985
|
return createProvider2(preferredProviderId, providerConfig, rootDir);
|
|
12942
12986
|
}
|
|
12943
12987
|
async function generateOutputArtifacts(rootDir, input) {
|
|
@@ -13342,6 +13386,7 @@ function pageHashes(pages) {
|
|
|
13342
13386
|
}
|
|
13343
13387
|
async function buildManagedGraphPage(absolutePath, defaults, build) {
|
|
13344
13388
|
const existingContent = await fileExists(absolutePath) ? await fs19.readFile(absolutePath, "utf8") : null;
|
|
13389
|
+
let carriedContent = existingContent;
|
|
13345
13390
|
let existing = await loadExistingManagedPageState(absolutePath, {
|
|
13346
13391
|
status: defaults.status ?? "active",
|
|
13347
13392
|
managedBy: defaults.managedBy
|
|
@@ -13356,6 +13401,7 @@ async function buildManagedGraphPage(absolutePath, defaults, build) {
|
|
|
13356
13401
|
status: defaults.status ?? "active",
|
|
13357
13402
|
managedBy: defaults.managedBy
|
|
13358
13403
|
});
|
|
13404
|
+
carriedContent = await fs19.readFile(candidatePath, "utf8");
|
|
13359
13405
|
usedFallbackState = true;
|
|
13360
13406
|
break;
|
|
13361
13407
|
}
|
|
@@ -13368,13 +13414,13 @@ async function buildManagedGraphPage(absolutePath, defaults, build) {
|
|
|
13368
13414
|
managedBy: defaults.managedBy,
|
|
13369
13415
|
confidence: defaults.confidence
|
|
13370
13416
|
};
|
|
13371
|
-
let built = build(metadata);
|
|
13372
|
-
if (
|
|
13417
|
+
let built = build(metadata, carriedContent);
|
|
13418
|
+
if (carriedContent && carriedContent !== built.content) {
|
|
13373
13419
|
metadata = {
|
|
13374
13420
|
...metadata,
|
|
13375
13421
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
13376
13422
|
};
|
|
13377
|
-
built = build(metadata);
|
|
13423
|
+
built = build(metadata, carriedContent);
|
|
13378
13424
|
}
|
|
13379
13425
|
return built;
|
|
13380
13426
|
}
|
|
@@ -13425,7 +13471,10 @@ async function loadAnalysesBySourceIds(paths, sourceIds) {
|
|
|
13425
13471
|
);
|
|
13426
13472
|
return analyses.filter((analysis) => Boolean(analysis?.sourceId));
|
|
13427
13473
|
}
|
|
13428
|
-
async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
13474
|
+
async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
13475
|
+
const dataviewEnabled = config.profile.dataviewBlocks;
|
|
13476
|
+
const profilePresets = config.profile.presets;
|
|
13477
|
+
const dashboardPack = config.profile.dashboardPack;
|
|
13429
13478
|
const sourcePages = graph.pages.filter((page) => page.kind === "source");
|
|
13430
13479
|
const reviewPages = graph.pages.filter((page) => page.kind === "output" && page.path.startsWith("outputs/source-reviews/"));
|
|
13431
13480
|
const briefPages = graph.pages.filter((page) => page.kind === "output" && page.path.startsWith("outputs/source-briefs/"));
|
|
@@ -13445,6 +13494,8 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13445
13494
|
const stagedGuideBundles = (await Promise.all(
|
|
13446
13495
|
(await fs19.readdir(paths.approvalsDir, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory()).map(async (entry) => await readJsonFile(approvalManifestPath(paths, entry.name)))
|
|
13447
13496
|
)).filter((manifest) => Boolean(manifest)).filter((manifest) => manifest.bundleType === "guided_source" || manifest.bundleType === "guided_session").sort((left, right) => right.createdAt.localeCompare(left.createdAt)).slice(0, 12);
|
|
13497
|
+
const readerFocusPages = uniqueBy([...guidePages, ...briefPages, ...conceptPages, ...entityPages], (page) => page.id).slice(0, 8);
|
|
13498
|
+
const diligenceSessions = sourceSessions.filter((session) => session.status === "staged" || session.status === "awaiting_input").slice(0, 8);
|
|
13448
13499
|
const dashboards = [
|
|
13449
13500
|
{
|
|
13450
13501
|
relativePath: "dashboards/index.md",
|
|
@@ -13462,12 +13513,17 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13462
13513
|
"- [[dashboards/contradictions|Contradictions]]",
|
|
13463
13514
|
"- [[dashboards/open-questions|Open Questions]]",
|
|
13464
13515
|
"",
|
|
13465
|
-
"
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
|
|
13516
|
+
`Profile Presets: ${profilePresets.length ? profilePresets.map((preset) => `\`${preset}\``).join(", ") : "_default_"}`,
|
|
13517
|
+
`Dashboard Pack: \`${dashboardPack}\``,
|
|
13518
|
+
...dataviewEnabled ? [
|
|
13519
|
+
"",
|
|
13520
|
+
"```dataview",
|
|
13521
|
+
"TABLE file.mtime AS updated",
|
|
13522
|
+
'FROM "dashboards"',
|
|
13523
|
+
'WHERE file.name != "index"',
|
|
13524
|
+
"SORT file.mtime desc",
|
|
13525
|
+
"```"
|
|
13526
|
+
] : [],
|
|
13471
13527
|
""
|
|
13472
13528
|
].join("\n"),
|
|
13473
13529
|
{
|
|
@@ -13488,7 +13544,8 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13488
13544
|
backlinks: [],
|
|
13489
13545
|
schema_hash: schemaHash,
|
|
13490
13546
|
source_hashes: {},
|
|
13491
|
-
source_semantic_hashes: {}
|
|
13547
|
+
source_semantic_hashes: {},
|
|
13548
|
+
profile_presets: profilePresets
|
|
13492
13549
|
}
|
|
13493
13550
|
)
|
|
13494
13551
|
},
|
|
@@ -13500,13 +13557,16 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13500
13557
|
"# Recent Sources",
|
|
13501
13558
|
"",
|
|
13502
13559
|
...recentSourcePages.length ? recentSourcePages.map((page) => `- ${page.updatedAt}: [[${page.path.replace(/\.md$/, "")}|${page.title}]]`) : ["- No source pages yet."],
|
|
13503
|
-
"",
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
|
|
13508
|
-
|
|
13509
|
-
|
|
13560
|
+
...dashboardPack === "reader" && readerFocusPages.length ? ["", "## Reader Focus", "", ...readerFocusPages.map((page) => `- [[${page.path.replace(/\.md$/, "")}|${page.title}]]`)] : [],
|
|
13561
|
+
...dataviewEnabled ? [
|
|
13562
|
+
"",
|
|
13563
|
+
"```dataview",
|
|
13564
|
+
"TABLE source_type, occurred_at, participants",
|
|
13565
|
+
'FROM "sources"',
|
|
13566
|
+
"SORT updated_at desc",
|
|
13567
|
+
"LIMIT 25",
|
|
13568
|
+
"```"
|
|
13569
|
+
] : [],
|
|
13510
13570
|
""
|
|
13511
13571
|
].join("\n"),
|
|
13512
13572
|
{
|
|
@@ -13527,7 +13587,8 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13527
13587
|
backlinks: [],
|
|
13528
13588
|
schema_hash: schemaHash,
|
|
13529
13589
|
source_hashes: {},
|
|
13530
|
-
source_semantic_hashes: {}
|
|
13590
|
+
source_semantic_hashes: {},
|
|
13591
|
+
profile_presets: profilePresets
|
|
13531
13592
|
}
|
|
13532
13593
|
)
|
|
13533
13594
|
},
|
|
@@ -13551,13 +13612,21 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13551
13612
|
(session) => `- ${session.updatedAt}: \`${session.status}\` [[outputs/source-sessions/${session.scopeId}|${session.scopeTitle}]]`
|
|
13552
13613
|
)
|
|
13553
13614
|
] : [],
|
|
13554
|
-
""
|
|
13555
|
-
|
|
13556
|
-
|
|
13557
|
-
|
|
13558
|
-
|
|
13559
|
-
|
|
13560
|
-
|
|
13615
|
+
...dashboardPack === "reader" && conceptPages.length ? [
|
|
13616
|
+
"",
|
|
13617
|
+
"## Thesis And Hub Pages",
|
|
13618
|
+
"",
|
|
13619
|
+
...conceptPages.slice(0, 6).map((page) => `- [[${page.path.replace(/\.md$/, "")}|${page.title}]]`)
|
|
13620
|
+
] : [],
|
|
13621
|
+
...dataviewEnabled ? [
|
|
13622
|
+
"",
|
|
13623
|
+
"```dataview",
|
|
13624
|
+
"TABLE occurred_at, source_type, participants, container_title",
|
|
13625
|
+
'FROM "sources"',
|
|
13626
|
+
"SORT occurred_at desc",
|
|
13627
|
+
"LIMIT 25",
|
|
13628
|
+
"```"
|
|
13629
|
+
] : [],
|
|
13561
13630
|
""
|
|
13562
13631
|
].join("\n"),
|
|
13563
13632
|
{
|
|
@@ -13578,7 +13647,8 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13578
13647
|
backlinks: [],
|
|
13579
13648
|
schema_hash: schemaHash,
|
|
13580
13649
|
source_hashes: {},
|
|
13581
|
-
source_semantic_hashes: {}
|
|
13650
|
+
source_semantic_hashes: {},
|
|
13651
|
+
profile_presets: profilePresets
|
|
13582
13652
|
}
|
|
13583
13653
|
)
|
|
13584
13654
|
},
|
|
@@ -13594,13 +13664,15 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13594
13664
|
const sourcePage = sourcePages.find((page) => page.sourceIds.includes(manifest.sourceId));
|
|
13595
13665
|
return `- ${occurredAt}: ${sourcePage ? `[[${sourcePage.path.replace(/\.md$/, "")}|${sourcePage.title}]]` : manifest.title}`;
|
|
13596
13666
|
}) : ["- No timeline-aware sources yet."],
|
|
13597
|
-
|
|
13598
|
-
|
|
13599
|
-
|
|
13600
|
-
|
|
13601
|
-
|
|
13602
|
-
|
|
13603
|
-
|
|
13667
|
+
...dataviewEnabled ? [
|
|
13668
|
+
"",
|
|
13669
|
+
"```dataview",
|
|
13670
|
+
"TABLE occurred_at, participants, container_title",
|
|
13671
|
+
'FROM "sources"',
|
|
13672
|
+
"WHERE occurred_at",
|
|
13673
|
+
"SORT occurred_at desc",
|
|
13674
|
+
"```"
|
|
13675
|
+
] : [],
|
|
13604
13676
|
""
|
|
13605
13677
|
].join("\n"),
|
|
13606
13678
|
{
|
|
@@ -13621,7 +13693,8 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13621
13693
|
backlinks: [],
|
|
13622
13694
|
schema_hash: schemaHash,
|
|
13623
13695
|
source_hashes: {},
|
|
13624
|
-
source_semantic_hashes: {}
|
|
13696
|
+
source_semantic_hashes: {},
|
|
13697
|
+
profile_presets: profilePresets
|
|
13625
13698
|
}
|
|
13626
13699
|
)
|
|
13627
13700
|
},
|
|
@@ -13643,11 +13716,14 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13643
13716
|
...stagedGuideBundles.length ? stagedGuideBundles.map(
|
|
13644
13717
|
(bundle) => `- ${bundle.createdAt}: \`${bundle.approvalId}\`${bundle.title ? ` ${bundle.title}` : ""} (${bundle.entries.length} staged entr${bundle.entries.length === 1 ? "y" : "ies"})`
|
|
13645
13718
|
) : ["- No staged guided bundles right now."],
|
|
13646
|
-
|
|
13647
|
-
|
|
13648
|
-
|
|
13649
|
-
|
|
13650
|
-
|
|
13719
|
+
...dataviewEnabled ? [
|
|
13720
|
+
"",
|
|
13721
|
+
"```dataview",
|
|
13722
|
+
"TABLE session_status, evidence_state, canonical_targets",
|
|
13723
|
+
'FROM "outputs/source-sessions"',
|
|
13724
|
+
"SORT file.mtime desc",
|
|
13725
|
+
"```"
|
|
13726
|
+
] : [],
|
|
13651
13727
|
""
|
|
13652
13728
|
].join("\n"),
|
|
13653
13729
|
{
|
|
@@ -13674,7 +13750,8 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13674
13750
|
backlinks: [],
|
|
13675
13751
|
schema_hash: schemaHash,
|
|
13676
13752
|
source_hashes: {},
|
|
13677
|
-
source_semantic_hashes: {}
|
|
13753
|
+
source_semantic_hashes: {},
|
|
13754
|
+
profile_presets: profilePresets
|
|
13678
13755
|
}
|
|
13679
13756
|
)
|
|
13680
13757
|
},
|
|
@@ -13692,11 +13769,14 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13692
13769
|
...stagedGuideBundles.length ? stagedGuideBundles.map(
|
|
13693
13770
|
(bundle) => `- ${bundle.createdAt}: \`${bundle.approvalId}\`${bundle.title ? ` ${bundle.title}` : ""} (${bundle.entries.length} staged entr${bundle.entries.length === 1 ? "y" : "ies"})`
|
|
13694
13771
|
) : ["- No staged guided bundles right now."],
|
|
13695
|
-
|
|
13696
|
-
|
|
13697
|
-
|
|
13698
|
-
|
|
13699
|
-
|
|
13772
|
+
...dataviewEnabled ? [
|
|
13773
|
+
"",
|
|
13774
|
+
"```dataview",
|
|
13775
|
+
"TABLE evidence_state, canonical_targets, file.mtime AS updated",
|
|
13776
|
+
'FROM "outputs/source-guides"',
|
|
13777
|
+
"SORT file.mtime desc",
|
|
13778
|
+
"```"
|
|
13779
|
+
] : [],
|
|
13700
13780
|
""
|
|
13701
13781
|
].join("\n"),
|
|
13702
13782
|
{
|
|
@@ -13723,7 +13803,8 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13723
13803
|
backlinks: [],
|
|
13724
13804
|
schema_hash: schemaHash,
|
|
13725
13805
|
source_hashes: {},
|
|
13726
|
-
source_semantic_hashes: {}
|
|
13806
|
+
source_semantic_hashes: {},
|
|
13807
|
+
profile_presets: profilePresets
|
|
13727
13808
|
}
|
|
13728
13809
|
)
|
|
13729
13810
|
},
|
|
@@ -13750,12 +13831,14 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13750
13831
|
"",
|
|
13751
13832
|
...sourceSessions.length ? sourceSessions.slice(0, 8).map((session) => `- \`${session.status}\` [[outputs/source-sessions/${session.scopeId}|${session.scopeTitle}]]`) : ["- No active source sessions yet."],
|
|
13752
13833
|
...report?.suggestedQuestions?.length ? ["", "## Suggested Questions", "", ...report.suggestedQuestions.slice(0, 8).map((question) => `- ${question}`)] : [],
|
|
13753
|
-
|
|
13754
|
-
|
|
13755
|
-
|
|
13756
|
-
|
|
13757
|
-
|
|
13758
|
-
|
|
13834
|
+
...dataviewEnabled ? [
|
|
13835
|
+
"",
|
|
13836
|
+
"```dataview",
|
|
13837
|
+
'TABLE file.folder, file.mtime FROM "concepts" OR "entities"',
|
|
13838
|
+
"SORT file.mtime desc",
|
|
13839
|
+
"LIMIT 30",
|
|
13840
|
+
"```"
|
|
13841
|
+
] : [],
|
|
13759
13842
|
""
|
|
13760
13843
|
].join("\n"),
|
|
13761
13844
|
{
|
|
@@ -13784,7 +13867,8 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13784
13867
|
backlinks: [],
|
|
13785
13868
|
schema_hash: schemaHash,
|
|
13786
13869
|
source_hashes: {},
|
|
13787
|
-
source_semantic_hashes: {}
|
|
13870
|
+
source_semantic_hashes: {},
|
|
13871
|
+
profile_presets: profilePresets
|
|
13788
13872
|
}
|
|
13789
13873
|
)
|
|
13790
13874
|
},
|
|
@@ -13807,10 +13891,21 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13807
13891
|
...[...guidePages, ...reviewPages, ...briefPages].slice(0, 12).map((page) => `- [[${page.path.replace(/\.md$/, "")}|${page.title}]]`),
|
|
13808
13892
|
""
|
|
13809
13893
|
] : [],
|
|
13810
|
-
"
|
|
13811
|
-
|
|
13812
|
-
|
|
13813
|
-
|
|
13894
|
+
...dashboardPack === "diligence" && diligenceSessions.length ? [
|
|
13895
|
+
"## Active Evidence Review Sessions",
|
|
13896
|
+
"",
|
|
13897
|
+
...diligenceSessions.map(
|
|
13898
|
+
(session) => `- \`${session.status}\` [[outputs/source-sessions/${session.scopeId}|${session.scopeTitle}]]`
|
|
13899
|
+
),
|
|
13900
|
+
""
|
|
13901
|
+
] : [],
|
|
13902
|
+
...dataviewEnabled ? [
|
|
13903
|
+
"```dataview",
|
|
13904
|
+
'TABLE evidence_state, session_status, canonical_targets FROM "outputs/source-reviews" OR "outputs/source-guides" OR "outputs/source-sessions"',
|
|
13905
|
+
'WHERE evidence_state = "conflicting"',
|
|
13906
|
+
"SORT file.mtime desc",
|
|
13907
|
+
"```"
|
|
13908
|
+
] : [],
|
|
13814
13909
|
""
|
|
13815
13910
|
].join("\n"),
|
|
13816
13911
|
{
|
|
@@ -13831,7 +13926,8 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13831
13926
|
backlinks: [],
|
|
13832
13927
|
schema_hash: schemaHash,
|
|
13833
13928
|
source_hashes: {},
|
|
13834
|
-
source_semantic_hashes: {}
|
|
13929
|
+
source_semantic_hashes: {},
|
|
13930
|
+
profile_presets: profilePresets
|
|
13835
13931
|
}
|
|
13836
13932
|
)
|
|
13837
13933
|
},
|
|
@@ -13849,11 +13945,13 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13849
13945
|
"",
|
|
13850
13946
|
...sourceSessions.filter((session) => session.status === "awaiting_input" || session.status === "staged").slice(0, 8).map((session) => `- \`${session.status}\` [[outputs/source-sessions/${session.scopeId}|${session.scopeTitle}]]`)
|
|
13851
13947
|
] : [],
|
|
13852
|
-
|
|
13853
|
-
|
|
13854
|
-
|
|
13855
|
-
|
|
13856
|
-
|
|
13948
|
+
...dataviewEnabled ? [
|
|
13949
|
+
"",
|
|
13950
|
+
"```dataview",
|
|
13951
|
+
'TABLE question_state, session_status, evidence_state FROM "outputs/source-briefs" OR "outputs/source-reviews" OR "outputs/source-guides" OR "outputs/source-sessions"',
|
|
13952
|
+
"SORT file.mtime desc",
|
|
13953
|
+
"```"
|
|
13954
|
+
] : [],
|
|
13857
13955
|
""
|
|
13858
13956
|
].join("\n"),
|
|
13859
13957
|
{
|
|
@@ -13874,7 +13972,8 @@ async function buildDashboardRecords(paths, graph, schemaHash, report) {
|
|
|
13874
13972
|
backlinks: [],
|
|
13875
13973
|
schema_hash: schemaHash,
|
|
13876
13974
|
source_hashes: {},
|
|
13877
|
-
source_semantic_hashes: {}
|
|
13975
|
+
source_semantic_hashes: {},
|
|
13976
|
+
profile_presets: profilePresets
|
|
13878
13977
|
}
|
|
13879
13978
|
)
|
|
13880
13979
|
}
|
|
@@ -14766,7 +14865,7 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
14766
14865
|
confidence: 1,
|
|
14767
14866
|
compiledFrom: [manifest.sourceId]
|
|
14768
14867
|
},
|
|
14769
|
-
(metadata) => buildSourcePage(
|
|
14868
|
+
(metadata, existingContent) => buildSourcePage(
|
|
14770
14869
|
manifest,
|
|
14771
14870
|
analysis,
|
|
14772
14871
|
sourceSchemaHash,
|
|
@@ -14777,7 +14876,8 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
14777
14876
|
projectIds: sourceProjectIds,
|
|
14778
14877
|
extraTags: [...sourceCategoryTags, ...analysis.tags ?? []],
|
|
14779
14878
|
sourceClass: manifest.sourceClass
|
|
14780
|
-
}
|
|
14879
|
+
},
|
|
14880
|
+
existingContent
|
|
14781
14881
|
)
|
|
14782
14882
|
);
|
|
14783
14883
|
records.push(sourceRecord);
|
|
@@ -14867,7 +14967,7 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
14867
14967
|
compiledFrom: sourceIds,
|
|
14868
14968
|
statePathCandidates: fallbackPaths
|
|
14869
14969
|
},
|
|
14870
|
-
(metadata) => buildAggregatePage(
|
|
14970
|
+
(metadata, existingContent) => buildAggregatePage(
|
|
14871
14971
|
itemKind,
|
|
14872
14972
|
aggregate.name,
|
|
14873
14973
|
aggregate.descriptions,
|
|
@@ -14886,7 +14986,8 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
14886
14986
|
...aggregate.sourceAnalyses.map((item) => item.summary)
|
|
14887
14987
|
]),
|
|
14888
14988
|
sourceClass: aggregateSourceClass2
|
|
14889
|
-
}
|
|
14989
|
+
},
|
|
14990
|
+
existingContent
|
|
14890
14991
|
)
|
|
14891
14992
|
);
|
|
14892
14993
|
if (promoted && previousEntry?.status === "candidate") {
|
|
@@ -14940,6 +15041,7 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
14940
15041
|
);
|
|
14941
15042
|
const preliminaryPages = [...basePages, ...graphOrientation.records.map((record) => record.page)];
|
|
14942
15043
|
const dashboardRecords = await buildDashboardRecords(
|
|
15044
|
+
config,
|
|
14943
15045
|
paths,
|
|
14944
15046
|
{
|
|
14945
15047
|
...baseGraph,
|
|
@@ -15179,6 +15281,7 @@ async function refreshIndexesAndSearch(rootDir, pages) {
|
|
|
15179
15281
|
compileState?.generatedAt
|
|
15180
15282
|
) : { records: [], report: null };
|
|
15181
15283
|
const dashboardRecords = currentGraph ? await buildDashboardRecords(
|
|
15284
|
+
config,
|
|
15182
15285
|
paths,
|
|
15183
15286
|
{
|
|
15184
15287
|
...currentGraph,
|
|
@@ -16051,21 +16154,27 @@ async function ensureObsidianWorkspace(rootDir) {
|
|
|
16051
16154
|
]);
|
|
16052
16155
|
}
|
|
16053
16156
|
async function initVault(rootDir, options = {}) {
|
|
16054
|
-
const
|
|
16055
|
-
const { paths } = await initWorkspace(rootDir, { profile });
|
|
16157
|
+
const requestedProfile = options.profile ?? "default";
|
|
16158
|
+
const { config, paths } = await initWorkspace(rootDir, { profile: requestedProfile });
|
|
16159
|
+
const profile = config.profile;
|
|
16160
|
+
const isResearchProfile = profile.presets.length > 0 || profile.guidedSessionMode === "canonical_review" || profile.dataviewBlocks;
|
|
16056
16161
|
await installConfiguredAgents(rootDir);
|
|
16057
16162
|
const insightsIndexPath = path23.join(paths.wikiDir, "insights", "index.md");
|
|
16058
16163
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
16059
16164
|
await writeFileIfChanged(
|
|
16060
16165
|
insightsIndexPath,
|
|
16061
16166
|
matter9.stringify(
|
|
16062
|
-
(
|
|
16167
|
+
(isResearchProfile ? [
|
|
16063
16168
|
"# Insights",
|
|
16064
16169
|
"",
|
|
16065
16170
|
"Human-authored research notes live here.",
|
|
16066
16171
|
"",
|
|
16067
16172
|
"- Use this folder for thesis notes, reading reflections, synthesis drafts, and decisions you want to keep explicitly human-authored.",
|
|
16068
|
-
|
|
16173
|
+
...profile.guidedSessionMode === "canonical_review" ? [
|
|
16174
|
+
"- Guided sessions can stage approval-queued updates for canonical pages and fall back to `wiki/insights/` when a claim still needs judgment."
|
|
16175
|
+
] : [
|
|
16176
|
+
"- Guided sessions fall back to `wiki/insights/` for exploratory synthesis until you decide what should become canonical."
|
|
16177
|
+
],
|
|
16069
16178
|
"- Treat these pages as the human judgment layer for your vault.",
|
|
16070
16179
|
""
|
|
16071
16180
|
] : [
|
|
@@ -16148,16 +16257,21 @@ async function initVault(rootDir, options = {}) {
|
|
|
16148
16257
|
if (options.obsidian) {
|
|
16149
16258
|
await ensureObsidianWorkspace(rootDir);
|
|
16150
16259
|
}
|
|
16151
|
-
if (
|
|
16260
|
+
if (isResearchProfile) {
|
|
16152
16261
|
await writeFileIfChanged(
|
|
16153
16262
|
path23.join(paths.wikiDir, "insights", "research-playbook.md"),
|
|
16154
16263
|
matter9.stringify(
|
|
16155
16264
|
[
|
|
16156
|
-
"
|
|
16265
|
+
`# ${requestedProfile === "personal-research" ? "Personal Research Playbook" : "Research Playbook"}`,
|
|
16157
16266
|
"",
|
|
16158
16267
|
"- Add one source at a time with `swarmvault ingest <input> --guide` or `swarmvault source add <input> --guide`.",
|
|
16159
16268
|
"- Resume a guided session with `swarmvault source session <source-id-or-session-id>` whenever you want to answer the session prompts directly.",
|
|
16160
16269
|
"- Review `wiki/outputs/source-briefs/`, `wiki/outputs/source-reviews/`, `wiki/outputs/source-guides/`, and `wiki/outputs/source-sessions/` before accepting staged updates.",
|
|
16270
|
+
...profile.guidedSessionMode === "canonical_review" ? ["- Use `swarmvault review show --diff` to inspect staged canonical page edits before accepting them."] : ["- Keep exploratory synthesis in `wiki/insights/` until you are ready to promote it into canonical pages."],
|
|
16271
|
+
...profile.dataviewBlocks ? [
|
|
16272
|
+
"- Dataview-friendly fields are enabled in the dashboards, but every generated page should still read cleanly as plain markdown."
|
|
16273
|
+
] : [],
|
|
16274
|
+
...profile.presets.length ? [`- Active profile presets: ${profile.presets.map((preset) => `\`${preset}\``).join(", ")}.`] : [],
|
|
16161
16275
|
"- Keep unresolved questions visible in `wiki/dashboards/open-questions.md`.",
|
|
16162
16276
|
"- Use `swarmvault review list` and `swarmvault review show --diff` to decide what becomes canonical.",
|
|
16163
16277
|
""
|
|
@@ -16165,7 +16279,7 @@ async function initVault(rootDir, options = {}) {
|
|
|
16165
16279
|
{
|
|
16166
16280
|
page_id: "insights:research-playbook",
|
|
16167
16281
|
kind: "insight",
|
|
16168
|
-
title: "Personal Research Playbook",
|
|
16282
|
+
title: requestedProfile === "personal-research" ? "Personal Research Playbook" : "Research Playbook",
|
|
16169
16283
|
tags: ["insight", "research", "playbook"],
|
|
16170
16284
|
source_ids: [],
|
|
16171
16285
|
project_ids: [],
|
|
@@ -17098,7 +17212,7 @@ async function bootstrapDemo(rootDir, input) {
|
|
|
17098
17212
|
}
|
|
17099
17213
|
|
|
17100
17214
|
// src/mcp.ts
|
|
17101
|
-
var SERVER_VERSION = "0.6.
|
|
17215
|
+
var SERVER_VERSION = "0.6.1";
|
|
17102
17216
|
async function createMcpServer(rootDir) {
|
|
17103
17217
|
const server = new McpServer({
|
|
17104
17218
|
name: "swarmvault",
|
|
@@ -18417,6 +18531,9 @@ var GUIDED_SESSION_QUESTIONS = [
|
|
|
18417
18531
|
function defaultGuidedSessionQuestions() {
|
|
18418
18532
|
return GUIDED_SESSION_QUESTIONS.map((question) => ({ ...question }));
|
|
18419
18533
|
}
|
|
18534
|
+
function splitDelimitedDetail(value) {
|
|
18535
|
+
return value ? value.split(",").map((item) => item.trim()).filter(Boolean) : [];
|
|
18536
|
+
}
|
|
18420
18537
|
function normalizeGuidedAnswerValue(value) {
|
|
18421
18538
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
18422
18539
|
}
|
|
@@ -18445,6 +18562,40 @@ function mergeGuidedSessionQuestions(questions, answers) {
|
|
|
18445
18562
|
function answeredGuidedSessionQuestions(questions) {
|
|
18446
18563
|
return questions.filter((question) => typeof question.answer === "string" && question.answer.trim().length > 0);
|
|
18447
18564
|
}
|
|
18565
|
+
function questionStateForSession(session) {
|
|
18566
|
+
return answeredGuidedSessionQuestions(session.questions).length === session.questions.length ? "answered" : "awaiting_input";
|
|
18567
|
+
}
|
|
18568
|
+
function manifestsForScope(graph, scope) {
|
|
18569
|
+
if (!graph) {
|
|
18570
|
+
return [];
|
|
18571
|
+
}
|
|
18572
|
+
const scopeSet = new Set(scope.sourceIds);
|
|
18573
|
+
return graph.sources.filter((manifest) => scopeSet.has(manifest.sourceId));
|
|
18574
|
+
}
|
|
18575
|
+
function scopeSourceType(scope, manifests) {
|
|
18576
|
+
return scope.kind ?? manifests[0]?.sourceKind ?? manifests[0]?.sourceType;
|
|
18577
|
+
}
|
|
18578
|
+
function scopeOccurredAt(manifests) {
|
|
18579
|
+
return manifests.map((manifest) => manifest.details?.occurred_at).filter((value) => typeof value === "string" && value.trim().length > 0).sort((left, right) => right.localeCompare(left))[0];
|
|
18580
|
+
}
|
|
18581
|
+
function scopeParticipants(manifests) {
|
|
18582
|
+
return uniqueStrings4(manifests.flatMap((manifest) => splitDelimitedDetail(manifest.details?.participants)));
|
|
18583
|
+
}
|
|
18584
|
+
function scopeContainerTitle(manifests) {
|
|
18585
|
+
return manifests.find((manifest) => manifest.details?.container_title)?.details?.container_title ?? manifests[0]?.sourceGroupTitle;
|
|
18586
|
+
}
|
|
18587
|
+
function scopeConversationId(manifests) {
|
|
18588
|
+
return manifests.find((manifest) => manifest.details?.conversation_id)?.details?.conversation_id;
|
|
18589
|
+
}
|
|
18590
|
+
function classifyGuidedEvidenceState(scope, targetPage, contradictions) {
|
|
18591
|
+
if (contradictions.length) {
|
|
18592
|
+
return "conflicting";
|
|
18593
|
+
}
|
|
18594
|
+
if (!targetPage) {
|
|
18595
|
+
return "needs_judgment";
|
|
18596
|
+
}
|
|
18597
|
+
return targetPage.sourceIds.some((sourceId) => !scope.sourceIds.includes(sourceId)) ? "reinforcing" : "new";
|
|
18598
|
+
}
|
|
18448
18599
|
function renderDeterministicSourceReview(input) {
|
|
18449
18600
|
const canonicalPages = input.sourcePages.filter((page) => page.kind === "source" || page.kind === "concept" || page.kind === "entity").slice(0, 10);
|
|
18450
18601
|
const modulePages = input.sourcePages.filter((page) => page.kind === "module").slice(0, 8);
|
|
@@ -18545,12 +18696,13 @@ Entities: ${analysis.entities.map((entity) => entity.name).join(", ") || "none"}
|
|
|
18545
18696
|
}
|
|
18546
18697
|
}
|
|
18547
18698
|
async function buildSourceReviewStagedPage(rootDir, scope) {
|
|
18548
|
-
const { paths } = await loadVaultConfig(rootDir);
|
|
18699
|
+
const { config, paths } = await loadVaultConfig(rootDir);
|
|
18549
18700
|
const markdown = await generateSourceReviewMarkdown(rootDir, scope);
|
|
18550
18701
|
if (!markdown) {
|
|
18551
18702
|
throw new Error(`Could not generate a source review for ${scope.id}.`);
|
|
18552
18703
|
}
|
|
18553
18704
|
const graph = await readJsonFile(paths.graphPath);
|
|
18705
|
+
const scopeManifests = manifestsForScope(graph, scope);
|
|
18554
18706
|
const relatedPages = graph ? scopedSourcePages(graph, scope.sourceIds) : [];
|
|
18555
18707
|
const relatedPageIds = relatedPages.slice(0, 16).map((page) => page.id);
|
|
18556
18708
|
const relatedNodeIds = graph ? scopedNodeIds(graph, scope.sourceIds).slice(0, 24) : [];
|
|
@@ -18577,13 +18729,26 @@ async function buildSourceReviewStagedPage(rootDir, scope) {
|
|
|
18577
18729
|
compiledFrom: scope.sourceIds,
|
|
18578
18730
|
managedBy: "system",
|
|
18579
18731
|
confidence: 0.79
|
|
18732
|
+
},
|
|
18733
|
+
frontmatter: {
|
|
18734
|
+
profile_presets: config.profile.presets,
|
|
18735
|
+
source_type: scopeSourceType(scope, scopeManifests),
|
|
18736
|
+
occurred_at: scopeOccurredAt(scopeManifests),
|
|
18737
|
+
participants: scopeParticipants(scopeManifests),
|
|
18738
|
+
container_title: scopeContainerTitle(scopeManifests),
|
|
18739
|
+
conversation_id: scopeConversationId(scopeManifests),
|
|
18740
|
+
question_state: "answered",
|
|
18741
|
+
canonical_targets: relatedPages.filter((page) => page.kind === "source" || page.kind === "concept" || page.kind === "entity").slice(0, 8).map((page) => page.path),
|
|
18742
|
+
evidence_state: findContradictionsForScope(scope, await readGraphReport(rootDir)).length ? "conflicting" : "needs_judgment"
|
|
18580
18743
|
}
|
|
18581
18744
|
});
|
|
18582
18745
|
return { page: output.page, content: output.content };
|
|
18583
18746
|
}
|
|
18584
18747
|
function classifySourceGuidePageBuckets(sourcePages, scopeSourceIds) {
|
|
18585
18748
|
const scopeSet = new Set(scopeSourceIds);
|
|
18586
|
-
const canonicalPages = sourcePages.filter(
|
|
18749
|
+
const canonicalPages = sourcePages.filter(
|
|
18750
|
+
(page) => (page.kind === "source" || page.kind === "concept" || page.kind === "entity") && (page.kind === "source" || page.status !== "candidate")
|
|
18751
|
+
).slice(0, 12);
|
|
18587
18752
|
const newPages = canonicalPages.filter((page) => page.sourceIds.every((sourceId) => scopeSet.has(sourceId))).slice(0, 6);
|
|
18588
18753
|
const reinforcingPages = canonicalPages.filter((page) => page.sourceIds.some((sourceId) => !scopeSet.has(sourceId))).slice(0, 6);
|
|
18589
18754
|
return { canonicalPages, newPages, reinforcingPages };
|
|
@@ -18776,13 +18941,16 @@ Entities: ${analysis.entities.map((entity) => entity.name).join(", ") || "none"}
|
|
|
18776
18941
|
}
|
|
18777
18942
|
}
|
|
18778
18943
|
async function buildSourceGuideStagedPage(rootDir, scope) {
|
|
18779
|
-
const { paths } = await loadVaultConfig(rootDir);
|
|
18944
|
+
const { config, paths } = await loadVaultConfig(rootDir);
|
|
18780
18945
|
const markdown = await generateSourceGuideMarkdown(rootDir, scope);
|
|
18781
18946
|
if (!markdown) {
|
|
18782
18947
|
throw new Error(`Could not generate a source guide for ${scope.id}.`);
|
|
18783
18948
|
}
|
|
18784
18949
|
const graph = await readJsonFile(paths.graphPath);
|
|
18950
|
+
const scopeManifests = manifestsForScope(graph, scope);
|
|
18785
18951
|
const relatedPages = graph ? scopedSourcePages(graph, scope.sourceIds) : [];
|
|
18952
|
+
const contradictions = findContradictionsForScope(scope, await readGraphReport(rootDir));
|
|
18953
|
+
const selectedTargets = selectGuidedTargetPages(scope, relatedPages, defaultGuidedSessionQuestions());
|
|
18786
18954
|
const relatedPageIds = relatedPages.slice(0, 18).map((page) => page.id);
|
|
18787
18955
|
const relatedNodeIds = graph ? scopedNodeIds(graph, scope.sourceIds).slice(0, 28) : [];
|
|
18788
18956
|
const projectIds = uniqueStrings4(relatedPages.flatMap((page) => page.projectIds));
|
|
@@ -18808,6 +18976,17 @@ async function buildSourceGuideStagedPage(rootDir, scope) {
|
|
|
18808
18976
|
compiledFrom: scope.sourceIds,
|
|
18809
18977
|
managedBy: "system",
|
|
18810
18978
|
confidence: 0.8
|
|
18979
|
+
},
|
|
18980
|
+
frontmatter: {
|
|
18981
|
+
profile_presets: config.profile.presets,
|
|
18982
|
+
source_type: scopeSourceType(scope, scopeManifests),
|
|
18983
|
+
occurred_at: scopeOccurredAt(scopeManifests),
|
|
18984
|
+
participants: scopeParticipants(scopeManifests),
|
|
18985
|
+
container_title: scopeContainerTitle(scopeManifests),
|
|
18986
|
+
conversation_id: scopeConversationId(scopeManifests),
|
|
18987
|
+
question_state: "answered",
|
|
18988
|
+
canonical_targets: selectedTargets.map((page) => page.path),
|
|
18989
|
+
evidence_state: contradictions.length ? "conflicting" : selectedTargets.some((page) => page.sourceIds.some((sourceId) => !scope.sourceIds.includes(sourceId))) ? "reinforcing" : selectedTargets.length ? "new" : "needs_judgment"
|
|
18811
18990
|
}
|
|
18812
18991
|
});
|
|
18813
18992
|
return { page: output.page, content: output.content };
|
|
@@ -18864,12 +19043,13 @@ async function prepareGuidedSourceSession(rootDir, scope, answers) {
|
|
|
18864
19043
|
return { session, statePath };
|
|
18865
19044
|
}
|
|
18866
19045
|
async function buildSourceSessionSavedPage(rootDir, scope, session) {
|
|
18867
|
-
const { paths } = await loadVaultConfig(rootDir);
|
|
19046
|
+
const { config, paths } = await loadVaultConfig(rootDir);
|
|
18868
19047
|
let graph = await readJsonFile(paths.graphPath);
|
|
18869
19048
|
if (!graph) {
|
|
18870
19049
|
await compileVault(rootDir, {});
|
|
18871
19050
|
graph = await readJsonFile(paths.graphPath);
|
|
18872
19051
|
}
|
|
19052
|
+
const scopeManifests = manifestsForScope(graph, scope);
|
|
18873
19053
|
const sourcePages = graph ? scopedSourcePages(graph, scope.sourceIds) : [];
|
|
18874
19054
|
const analyses = await loadSourceAnalyses(rootDir, scope.sourceIds);
|
|
18875
19055
|
const report = await readGraphReport(rootDir);
|
|
@@ -18883,6 +19063,9 @@ async function buildSourceSessionSavedPage(rootDir, scope, session) {
|
|
|
18883
19063
|
]);
|
|
18884
19064
|
const relatedNodeIds = graph ? scopedNodeIds(graph, scope.sourceIds).slice(0, 28) : [];
|
|
18885
19065
|
const projectIds = uniqueStrings4(sourcePages.flatMap((page) => page.projectIds));
|
|
19066
|
+
const evidenceState = contradictions.length > 0 ? "conflicting" : session.targetedPagePaths.some(
|
|
19067
|
+
(targetPath) => sourcePages.some((page) => page.path === targetPath && page.sourceIds.some((sourceId) => !scope.sourceIds.includes(sourceId)))
|
|
19068
|
+
) ? "reinforcing" : session.targetedPagePaths.length ? "new" : "needs_judgment";
|
|
18886
19069
|
const relativeBriefPath = session.briefPath && path26.isAbsolute(session.briefPath) ? path26.relative(paths.wikiDir, session.briefPath) : session.briefPath;
|
|
18887
19070
|
const sessionMarkdown = [
|
|
18888
19071
|
`# Guided Session: ${scope.title}`,
|
|
@@ -18947,6 +19130,18 @@ async function buildSourceSessionSavedPage(rootDir, scope, session) {
|
|
|
18947
19130
|
compiledFrom: scope.sourceIds,
|
|
18948
19131
|
managedBy: "system",
|
|
18949
19132
|
confidence: 0.81
|
|
19133
|
+
},
|
|
19134
|
+
frontmatter: {
|
|
19135
|
+
profile_presets: config.profile.presets,
|
|
19136
|
+
source_type: scopeSourceType(scope, scopeManifests),
|
|
19137
|
+
occurred_at: scopeOccurredAt(scopeManifests),
|
|
19138
|
+
participants: scopeParticipants(scopeManifests),
|
|
19139
|
+
container_title: scopeContainerTitle(scopeManifests),
|
|
19140
|
+
conversation_id: scopeConversationId(scopeManifests),
|
|
19141
|
+
session_status: session.status,
|
|
19142
|
+
question_state: questionStateForSession(session),
|
|
19143
|
+
canonical_targets: session.targetedPagePaths,
|
|
19144
|
+
evidence_state: evidenceState
|
|
18950
19145
|
}
|
|
18951
19146
|
});
|
|
18952
19147
|
return { page: output.page, content: output.content };
|
|
@@ -18959,8 +19154,8 @@ async function persistSourceSessionPage(rootDir, scope, session) {
|
|
|
18959
19154
|
await fs22.writeFile(absolutePath, output.content, "utf8");
|
|
18960
19155
|
return { pageId: output.page.id, sessionPath: absolutePath };
|
|
18961
19156
|
}
|
|
18962
|
-
async function
|
|
18963
|
-
const { paths } = await loadVaultConfig(rootDir);
|
|
19157
|
+
async function buildGuidedUpdatePages(rootDir, scope, session) {
|
|
19158
|
+
const { config, paths } = await loadVaultConfig(rootDir);
|
|
18964
19159
|
let graph = await readJsonFile(paths.graphPath);
|
|
18965
19160
|
if (!graph) {
|
|
18966
19161
|
await compileVault(rootDir, {});
|
|
@@ -18970,14 +19165,20 @@ async function buildGuidedInsightUpdatePages(rootDir, scope, session) {
|
|
|
18970
19165
|
return [];
|
|
18971
19166
|
}
|
|
18972
19167
|
const sourcePages = scopedSourcePages(graph, scope.sourceIds);
|
|
19168
|
+
const scopeManifests = manifestsForScope(graph, scope);
|
|
18973
19169
|
const analyses = await loadSourceAnalyses(rootDir, scope.sourceIds);
|
|
18974
19170
|
const report = await readGraphReport(rootDir);
|
|
18975
19171
|
const contradictions = findContradictionsForScope(scope, report);
|
|
18976
19172
|
const selectedTargets = selectGuidedTargetPages(scope, sourcePages, session.questions);
|
|
18977
|
-
const
|
|
19173
|
+
const useCanonicalTargets = config.profile.guidedSessionMode === "canonical_review" && selectedTargets.length > 0;
|
|
19174
|
+
const targetPages = useCanonicalTargets ? selectedTargets : [selectedTargets[0] ?? null];
|
|
19175
|
+
session.targetedPagePaths = uniqueStrings4(
|
|
19176
|
+
useCanonicalTargets ? selectedTargets.map((page) => page.path) : selectedTargets.length ? selectedTargets.map((page) => page.path) : session.targetedPagePaths
|
|
19177
|
+
);
|
|
18978
19178
|
return await Promise.all(
|
|
18979
|
-
targetPages.map(async (targetPage
|
|
18980
|
-
const
|
|
19179
|
+
targetPages.map(async (targetPage) => {
|
|
19180
|
+
const evidenceState = classifyGuidedEvidenceState(scope, targetPage, contradictions);
|
|
19181
|
+
const relativePath = useCanonicalTargets && targetPage ? targetPage.path : targetPage ? insightRelativePathForTarget(targetPage, scope) : `insights/topics/${slugify(scope.title)}.md`;
|
|
18981
19182
|
const absolutePath = path26.join(paths.wikiDir, relativePath);
|
|
18982
19183
|
const existingContent = await fileExists(absolutePath) ? await fs22.readFile(absolutePath, "utf8") : "";
|
|
18983
19184
|
const parsed = existingContent ? matter10(existingContent) : { data: {}, content: "" };
|
|
@@ -18987,8 +19188,13 @@ async function buildGuidedInsightUpdatePages(rootDir, scope, session) {
|
|
|
18987
19188
|
const existingNodeIds = Array.isArray(existingData.node_ids) ? existingData.node_ids.filter((value) => typeof value === "string") : [];
|
|
18988
19189
|
const existingBacklinks = Array.isArray(existingData.backlinks) ? existingData.backlinks.filter((value) => typeof value === "string") : [];
|
|
18989
19190
|
const createdAt = typeof existingData.created_at === "string" && existingData.created_at.trim() ? existingData.created_at : (/* @__PURE__ */ new Date()).toISOString();
|
|
18990
|
-
const title = typeof existingData.title === "string" && existingData.title.trim() || (targetPage ? insightTitleForTarget(targetPage, scope) : `${scope.title} Notes`);
|
|
18991
|
-
const baseBody = parsed.content.trim() ? parsed.content.trim() : [
|
|
19191
|
+
const title = typeof existingData.title === "string" && existingData.title.trim() || (useCanonicalTargets && targetPage ? targetPage.title : targetPage ? insightTitleForTarget(targetPage, scope) : `${scope.title} Notes`);
|
|
19192
|
+
const baseBody = parsed.content.trim() ? parsed.content.trim() : [
|
|
19193
|
+
`# ${title}`,
|
|
19194
|
+
"",
|
|
19195
|
+
useCanonicalTargets ? "Canonical page maintained by SwarmVault. Guided sessions stage replaceable update blocks here for approval." : "Human-curated insight page. Guided sessions stage replaceable update blocks here.",
|
|
19196
|
+
""
|
|
19197
|
+
].join("\n");
|
|
18992
19198
|
const importance = questionAnswer(
|
|
18993
19199
|
session.questions,
|
|
18994
19200
|
"importance",
|
|
@@ -19008,6 +19214,7 @@ async function buildGuidedInsightUpdatePages(rootDir, scope, session) {
|
|
|
19008
19214
|
const updateBlock = [
|
|
19009
19215
|
`## Guided Session Update: ${scope.title}`,
|
|
19010
19216
|
"",
|
|
19217
|
+
`Evidence State: \`${evidenceState}\``,
|
|
19011
19218
|
`Session: [[outputs/source-sessions/${scope.id}|Guided Session]]`,
|
|
19012
19219
|
`Source Guide: [[outputs/source-guides/${scope.id}|Source Guide]]`,
|
|
19013
19220
|
"",
|
|
@@ -19035,48 +19242,60 @@ async function buildGuidedInsightUpdatePages(rootDir, scope, session) {
|
|
|
19035
19242
|
""
|
|
19036
19243
|
].join("\n");
|
|
19037
19244
|
const nextBody = replaceMarkedSection(baseBody, scope.id, updateBlock);
|
|
19038
|
-
const content = matter10.stringify(
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
|
|
19042
|
-
|
|
19043
|
-
|
|
19044
|
-
|
|
19045
|
-
|
|
19046
|
-
|
|
19047
|
-
|
|
19048
|
-
|
|
19049
|
-
|
|
19050
|
-
|
|
19051
|
-
|
|
19052
|
-
|
|
19053
|
-
|
|
19054
|
-
|
|
19055
|
-
|
|
19056
|
-
|
|
19057
|
-
|
|
19058
|
-
|
|
19059
|
-
|
|
19060
|
-
|
|
19061
|
-
|
|
19062
|
-
|
|
19063
|
-
|
|
19064
|
-
|
|
19065
|
-
|
|
19066
|
-
|
|
19067
|
-
|
|
19068
|
-
|
|
19069
|
-
|
|
19070
|
-
|
|
19245
|
+
const content = matter10.stringify(
|
|
19246
|
+
`${nextBody.trimEnd()}
|
|
19247
|
+
`,
|
|
19248
|
+
JSON.parse(
|
|
19249
|
+
JSON.stringify({
|
|
19250
|
+
...existingData,
|
|
19251
|
+
page_id: typeof existingData.page_id === "string" && existingData.page_id.trim() || (useCanonicalTargets && targetPage ? targetPage.id : `insight:${slugify(relativePath.replace(/\.md$/, ""))}`),
|
|
19252
|
+
kind: useCanonicalTargets && targetPage ? targetPage.kind : "insight",
|
|
19253
|
+
title,
|
|
19254
|
+
tags: uniqueStrings4([
|
|
19255
|
+
...Array.isArray(existingData.tags) ? existingData.tags.filter((value) => typeof value === "string") : [],
|
|
19256
|
+
...useCanonicalTargets ? ["guided-session", `guided/${targetPage?.kind ?? "page"}`] : insightTagsForTarget(targetPage)
|
|
19257
|
+
]),
|
|
19258
|
+
source_ids: uniqueStrings4([...existingSourceIds, ...scope.sourceIds]),
|
|
19259
|
+
project_ids: uniqueStrings4([...existingProjectIds, ...targetPage?.projectIds ?? []]),
|
|
19260
|
+
node_ids: uniqueStrings4([...existingNodeIds, ...targetPage?.nodeIds ?? []]),
|
|
19261
|
+
freshness: "fresh",
|
|
19262
|
+
status: existingData.status === "archived" ? "archived" : "active",
|
|
19263
|
+
confidence: 0.83,
|
|
19264
|
+
created_at: createdAt,
|
|
19265
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19266
|
+
compiled_from: uniqueStrings4([
|
|
19267
|
+
...Array.isArray(existingData.compiled_from) ? existingData.compiled_from.filter((value) => typeof value === "string") : [],
|
|
19268
|
+
...scope.sourceIds
|
|
19269
|
+
]),
|
|
19270
|
+
managed_by: typeof existingData.managed_by === "string" && (existingData.managed_by === "human" || existingData.managed_by === "system") ? existingData.managed_by : useCanonicalTargets ? "system" : "human",
|
|
19271
|
+
backlinks: uniqueStrings4([
|
|
19272
|
+
...existingBacklinks,
|
|
19273
|
+
...targetPage ? [targetPage.id] : [],
|
|
19274
|
+
`output:source-sessions/${scope.id}`,
|
|
19275
|
+
`output:source-guides/${scope.id}`
|
|
19276
|
+
]),
|
|
19277
|
+
schema_hash: typeof existingData.schema_hash === "string" ? existingData.schema_hash : "",
|
|
19278
|
+
source_hashes: existingData.source_hashes && typeof existingData.source_hashes === "object" ? existingData.source_hashes : {},
|
|
19279
|
+
source_semantic_hashes: existingData.source_semantic_hashes && typeof existingData.source_semantic_hashes === "object" ? existingData.source_semantic_hashes : {},
|
|
19280
|
+
profile_presets: config.profile.presets,
|
|
19281
|
+
source_type: scopeSourceType(scope, scopeManifests),
|
|
19282
|
+
occurred_at: scopeOccurredAt(scopeManifests),
|
|
19283
|
+
participants: scopeParticipants(scopeManifests),
|
|
19284
|
+
container_title: scopeContainerTitle(scopeManifests),
|
|
19285
|
+
conversation_id: scopeConversationId(scopeManifests),
|
|
19286
|
+
session_status: session.status,
|
|
19287
|
+
question_state: questionStateForSession(session),
|
|
19288
|
+
canonical_targets: useCanonicalTargets ? selectedTargets.map((page2) => page2.path) : [],
|
|
19289
|
+
evidence_state: evidenceState
|
|
19290
|
+
})
|
|
19291
|
+
)
|
|
19292
|
+
);
|
|
19071
19293
|
const page = parseStoredPage(relativePath, content, {
|
|
19072
19294
|
createdAt,
|
|
19073
19295
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
19074
19296
|
});
|
|
19075
|
-
if (
|
|
19076
|
-
session.targetedPagePaths = uniqueStrings4([
|
|
19077
|
-
...session.targetedPagePaths,
|
|
19078
|
-
...selectedTargets.length ? selectedTargets.map((page2) => page2.path) : [relativePath]
|
|
19079
|
-
]);
|
|
19297
|
+
if (!useCanonicalTargets && !selectedTargets.length) {
|
|
19298
|
+
session.targetedPagePaths = uniqueStrings4([...session.targetedPagePaths, relativePath]);
|
|
19080
19299
|
}
|
|
19081
19300
|
return { page, content, label: "guided-update" };
|
|
19082
19301
|
})
|
|
@@ -19116,7 +19335,7 @@ async function stageSourceGuideForScope(rootDir, scope, options = {}) {
|
|
|
19116
19335
|
...scope,
|
|
19117
19336
|
briefPath
|
|
19118
19337
|
});
|
|
19119
|
-
const guidedUpdates = await
|
|
19338
|
+
const guidedUpdates = await buildGuidedUpdatePages(rootDir, scope, session);
|
|
19120
19339
|
session.stagedUpdatePaths = guidedUpdates.map((item) => item.page.path);
|
|
19121
19340
|
const approval = await stageGeneratedOutputPages(
|
|
19122
19341
|
rootDir,
|