@swarmvaultai/engine 0.11.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +97 -1
- package/dist/index.js +714 -381
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8379,15 +8379,15 @@ function sourceTypeForNode(node, pagesById) {
|
|
|
8379
8379
|
return pagesById.get(node.pageId)?.sourceType;
|
|
8380
8380
|
}
|
|
8381
8381
|
function supportingPathDetails(graph, edge) {
|
|
8382
|
-
const
|
|
8382
|
+
const path32 = shortestGraphPath(graph, edge.source, edge.target);
|
|
8383
8383
|
const edgesById = new Map(graph.edges.map((item) => [item.id, item]));
|
|
8384
|
-
const pathEdges =
|
|
8384
|
+
const pathEdges = path32.edgeIds.map((edgeId) => edgesById.get(edgeId)).filter((item) => Boolean(item));
|
|
8385
8385
|
return {
|
|
8386
|
-
pathNodeIds:
|
|
8387
|
-
pathEdgeIds:
|
|
8386
|
+
pathNodeIds: path32.nodeIds,
|
|
8387
|
+
pathEdgeIds: path32.edgeIds,
|
|
8388
8388
|
pathRelations: pathEdges.map((item) => item.relation),
|
|
8389
8389
|
pathEvidenceClasses: pathEdges.map((item) => item.evidenceClass),
|
|
8390
|
-
pathSummary:
|
|
8390
|
+
pathSummary: path32.summary
|
|
8391
8391
|
};
|
|
8392
8392
|
}
|
|
8393
8393
|
function surpriseScore(edge, graph, pagesById, hyperedgesByNodeId) {
|
|
@@ -8456,7 +8456,7 @@ function topSurprisingConnections(graph, pagesById) {
|
|
|
8456
8456
|
}).map((edge) => {
|
|
8457
8457
|
const source = nodesById.get(edge.source);
|
|
8458
8458
|
const target = nodesById.get(edge.target);
|
|
8459
|
-
const
|
|
8459
|
+
const path32 = supportingPathDetails(graph, edge);
|
|
8460
8460
|
const scored = surpriseScore(edge, graph, pagesById, hyperedgesByNodeId);
|
|
8461
8461
|
return {
|
|
8462
8462
|
id: edge.id,
|
|
@@ -8467,11 +8467,11 @@ function topSurprisingConnections(graph, pagesById) {
|
|
|
8467
8467
|
relation: edge.relation,
|
|
8468
8468
|
evidenceClass: edge.evidenceClass,
|
|
8469
8469
|
confidence: edge.confidence,
|
|
8470
|
-
pathNodeIds:
|
|
8471
|
-
pathEdgeIds:
|
|
8472
|
-
pathRelations:
|
|
8473
|
-
pathEvidenceClasses:
|
|
8474
|
-
pathSummary:
|
|
8470
|
+
pathNodeIds: path32.pathNodeIds,
|
|
8471
|
+
pathEdgeIds: path32.pathEdgeIds,
|
|
8472
|
+
pathRelations: path32.pathRelations,
|
|
8473
|
+
pathEvidenceClasses: path32.pathEvidenceClasses,
|
|
8474
|
+
pathSummary: path32.pathSummary,
|
|
8475
8475
|
why: scored.why,
|
|
8476
8476
|
explanation: scored.explanation,
|
|
8477
8477
|
surpriseScore: scored.score
|
|
@@ -18646,20 +18646,271 @@ async function readExtractionArtifact(rootDir, manifest) {
|
|
|
18646
18646
|
}
|
|
18647
18647
|
|
|
18648
18648
|
// src/mcp.ts
|
|
18649
|
-
import
|
|
18650
|
-
import
|
|
18649
|
+
import fs24 from "fs/promises";
|
|
18650
|
+
import path28 from "path";
|
|
18651
18651
|
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
18652
18652
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
18653
18653
|
import { z as z8 } from "zod";
|
|
18654
18654
|
|
|
18655
|
-
// src/
|
|
18655
|
+
// src/migrate.ts
|
|
18656
18656
|
import fs16 from "fs/promises";
|
|
18657
18657
|
import path17 from "path";
|
|
18658
|
+
import matter9 from "gray-matter";
|
|
18659
|
+
var VAULT_VERSION_FILENAME = "vault-version.json";
|
|
18660
|
+
async function walkMarkdownFiles(dir) {
|
|
18661
|
+
const results = [];
|
|
18662
|
+
let entries;
|
|
18663
|
+
try {
|
|
18664
|
+
entries = await fs16.readdir(dir, { withFileTypes: true });
|
|
18665
|
+
} catch {
|
|
18666
|
+
return results;
|
|
18667
|
+
}
|
|
18668
|
+
for (const entry of entries) {
|
|
18669
|
+
const full = path17.join(dir, entry.name);
|
|
18670
|
+
if (entry.isDirectory()) {
|
|
18671
|
+
results.push(...await walkMarkdownFiles(full));
|
|
18672
|
+
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
18673
|
+
results.push(full);
|
|
18674
|
+
}
|
|
18675
|
+
}
|
|
18676
|
+
return results;
|
|
18677
|
+
}
|
|
18678
|
+
async function readFrontmatterFile(filePath) {
|
|
18679
|
+
try {
|
|
18680
|
+
const raw = await fs16.readFile(filePath, "utf8");
|
|
18681
|
+
const parsed = matter9(raw);
|
|
18682
|
+
const data = parsed.data ?? {};
|
|
18683
|
+
return { data, content: parsed.content };
|
|
18684
|
+
} catch {
|
|
18685
|
+
return null;
|
|
18686
|
+
}
|
|
18687
|
+
}
|
|
18688
|
+
async function writeFrontmatterFile(filePath, data, content) {
|
|
18689
|
+
await fs16.writeFile(filePath, matter9.stringify(content, data), "utf8");
|
|
18690
|
+
}
|
|
18691
|
+
function relFromRoot(rootDir, filePath) {
|
|
18692
|
+
return path17.relative(rootDir, filePath) || filePath;
|
|
18693
|
+
}
|
|
18694
|
+
var MIGRATION_ADD_DECAY_FIELDS = {
|
|
18695
|
+
id: "0.9-to-0.10-add-decay-fields",
|
|
18696
|
+
fromVersion: "0.9.0",
|
|
18697
|
+
toVersion: "0.10.0",
|
|
18698
|
+
description: "Add decay_score and last_confirmed_at frontmatter to pages missing them.",
|
|
18699
|
+
async apply(ctx, options) {
|
|
18700
|
+
const changed = [];
|
|
18701
|
+
const files = await walkMarkdownFiles(ctx.paths.wikiDir);
|
|
18702
|
+
for (const filePath of files) {
|
|
18703
|
+
const parsed = await readFrontmatterFile(filePath);
|
|
18704
|
+
if (!parsed) continue;
|
|
18705
|
+
const { data, content } = parsed;
|
|
18706
|
+
if (!data.page_id) continue;
|
|
18707
|
+
let mutated = false;
|
|
18708
|
+
if (data.decay_score === void 0) {
|
|
18709
|
+
data.decay_score = 1;
|
|
18710
|
+
mutated = true;
|
|
18711
|
+
}
|
|
18712
|
+
if (data.last_confirmed_at === void 0) {
|
|
18713
|
+
data.last_confirmed_at = data.updated_at ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
18714
|
+
mutated = true;
|
|
18715
|
+
}
|
|
18716
|
+
if (mutated) {
|
|
18717
|
+
if (!options.dryRun) {
|
|
18718
|
+
await writeFrontmatterFile(filePath, data, content);
|
|
18719
|
+
}
|
|
18720
|
+
changed.push(relFromRoot(ctx.rootDir, filePath));
|
|
18721
|
+
}
|
|
18722
|
+
}
|
|
18723
|
+
return { changed };
|
|
18724
|
+
}
|
|
18725
|
+
};
|
|
18726
|
+
var MIGRATION_ADD_TIER_DEFAULT = {
|
|
18727
|
+
id: "0.9-to-0.10-add-tier-default",
|
|
18728
|
+
fromVersion: "0.9.0",
|
|
18729
|
+
toVersion: "0.10.0",
|
|
18730
|
+
description: 'Tag insight pages with tier: "working" when the field is absent.',
|
|
18731
|
+
async apply(ctx, options) {
|
|
18732
|
+
const changed = [];
|
|
18733
|
+
const insightsDir = path17.join(ctx.paths.wikiDir, "insights");
|
|
18734
|
+
const files = await walkMarkdownFiles(insightsDir);
|
|
18735
|
+
for (const filePath of files) {
|
|
18736
|
+
const parsed = await readFrontmatterFile(filePath);
|
|
18737
|
+
if (!parsed) continue;
|
|
18738
|
+
const { data, content } = parsed;
|
|
18739
|
+
if (data.kind !== "insight") continue;
|
|
18740
|
+
if (data.tier !== void 0) continue;
|
|
18741
|
+
data.tier = "working";
|
|
18742
|
+
if (!options.dryRun) {
|
|
18743
|
+
await writeFrontmatterFile(filePath, data, content);
|
|
18744
|
+
}
|
|
18745
|
+
changed.push(relFromRoot(ctx.rootDir, filePath));
|
|
18746
|
+
}
|
|
18747
|
+
return { changed };
|
|
18748
|
+
}
|
|
18749
|
+
};
|
|
18750
|
+
var MIGRATION_ADD_TAGS_FIELD = {
|
|
18751
|
+
id: "0.10-to-0.11-add-tags-field",
|
|
18752
|
+
fromVersion: "0.10.0",
|
|
18753
|
+
toVersion: "0.11.0",
|
|
18754
|
+
description: 'Add default tags: ["<kind>"] to derived concept and entity pages missing a tags array.',
|
|
18755
|
+
async apply(ctx, options) {
|
|
18756
|
+
const changed = [];
|
|
18757
|
+
const files = await walkMarkdownFiles(ctx.paths.wikiDir);
|
|
18758
|
+
for (const filePath of files) {
|
|
18759
|
+
const parsed = await readFrontmatterFile(filePath);
|
|
18760
|
+
if (!parsed) continue;
|
|
18761
|
+
const { data, content } = parsed;
|
|
18762
|
+
const kind = data.kind;
|
|
18763
|
+
if (kind !== "concept" && kind !== "entity") continue;
|
|
18764
|
+
if (Array.isArray(data.tags) && data.tags.length > 0) continue;
|
|
18765
|
+
data.tags = [kind];
|
|
18766
|
+
if (!options.dryRun) {
|
|
18767
|
+
await writeFrontmatterFile(filePath, data, content);
|
|
18768
|
+
}
|
|
18769
|
+
changed.push(relFromRoot(ctx.rootDir, filePath));
|
|
18770
|
+
}
|
|
18771
|
+
return { changed };
|
|
18772
|
+
}
|
|
18773
|
+
};
|
|
18774
|
+
var MIGRATION_NOTE_WATCH_BLOCK = {
|
|
18775
|
+
id: "0.10-to-0.11-normalize-config-watch-absence",
|
|
18776
|
+
fromVersion: "0.10.0",
|
|
18777
|
+
toVersion: "0.11.0",
|
|
18778
|
+
description: "Record that swarmvault.config.json watch block is optional in 0.11 (no file changes).",
|
|
18779
|
+
async apply() {
|
|
18780
|
+
return { changed: [] };
|
|
18781
|
+
}
|
|
18782
|
+
};
|
|
18783
|
+
var MIGRATION_REBUILD_SEARCH_INDEX = {
|
|
18784
|
+
id: "any-to-any-rebuild-search-index",
|
|
18785
|
+
fromVersion: "0.9.0",
|
|
18786
|
+
toVersion: "0.11.0",
|
|
18787
|
+
description: "Mark state/search.sqlite as stale so the next compile regenerates it.",
|
|
18788
|
+
async apply(ctx, options) {
|
|
18789
|
+
const changed = [];
|
|
18790
|
+
const searchPath = path17.join(ctx.paths.stateDir, "search.sqlite");
|
|
18791
|
+
try {
|
|
18792
|
+
await fs16.access(searchPath);
|
|
18793
|
+
if (!options.dryRun) {
|
|
18794
|
+
await fs16.rm(searchPath, { force: true });
|
|
18795
|
+
}
|
|
18796
|
+
changed.push(relFromRoot(ctx.rootDir, searchPath));
|
|
18797
|
+
} catch {
|
|
18798
|
+
}
|
|
18799
|
+
return { changed };
|
|
18800
|
+
}
|
|
18801
|
+
};
|
|
18802
|
+
var ALL_MIGRATIONS = [
|
|
18803
|
+
MIGRATION_ADD_DECAY_FIELDS,
|
|
18804
|
+
MIGRATION_ADD_TIER_DEFAULT,
|
|
18805
|
+
MIGRATION_ADD_TAGS_FIELD,
|
|
18806
|
+
MIGRATION_NOTE_WATCH_BLOCK,
|
|
18807
|
+
MIGRATION_REBUILD_SEARCH_INDEX
|
|
18808
|
+
];
|
|
18809
|
+
function compareSemver(a, b) {
|
|
18810
|
+
const pa = a.split(".").map((part) => Number.parseInt(part, 10));
|
|
18811
|
+
const pb = b.split(".").map((part) => Number.parseInt(part, 10));
|
|
18812
|
+
for (let i = 0; i < 3; i += 1) {
|
|
18813
|
+
const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
18814
|
+
if (diff !== 0) return diff > 0 ? 1 : -1;
|
|
18815
|
+
}
|
|
18816
|
+
return 0;
|
|
18817
|
+
}
|
|
18818
|
+
async function readVaultVersionRecord(stateDir) {
|
|
18819
|
+
const filePath = path17.join(stateDir, VAULT_VERSION_FILENAME);
|
|
18820
|
+
try {
|
|
18821
|
+
const raw = await fs16.readFile(filePath, "utf8");
|
|
18822
|
+
const parsed = JSON.parse(raw);
|
|
18823
|
+
if (typeof parsed.version === "string") return parsed;
|
|
18824
|
+
return null;
|
|
18825
|
+
} catch {
|
|
18826
|
+
return null;
|
|
18827
|
+
}
|
|
18828
|
+
}
|
|
18829
|
+
async function readGraphVersion(stateDir) {
|
|
18830
|
+
const filePath = path17.join(stateDir, "graph.json");
|
|
18831
|
+
try {
|
|
18832
|
+
const raw = await fs16.readFile(filePath, "utf8");
|
|
18833
|
+
const parsed = JSON.parse(raw);
|
|
18834
|
+
const version = parsed?.generatedBy?.version;
|
|
18835
|
+
return typeof version === "string" ? version : null;
|
|
18836
|
+
} catch {
|
|
18837
|
+
return null;
|
|
18838
|
+
}
|
|
18839
|
+
}
|
|
18840
|
+
async function detectVaultVersion(rootDir) {
|
|
18841
|
+
const { paths } = await initWorkspace(rootDir);
|
|
18842
|
+
const record = await readVaultVersionRecord(paths.stateDir);
|
|
18843
|
+
if (record) return record.version;
|
|
18844
|
+
const graphVersion = await readGraphVersion(paths.stateDir);
|
|
18845
|
+
if (graphVersion) return graphVersion;
|
|
18846
|
+
return null;
|
|
18847
|
+
}
|
|
18848
|
+
async function currentPackageVersion() {
|
|
18849
|
+
try {
|
|
18850
|
+
const raw = await fs16.readFile(new URL("../package.json", import.meta.url), "utf8");
|
|
18851
|
+
const parsed = JSON.parse(raw);
|
|
18852
|
+
return typeof parsed.version === "string" && parsed.version.trim() ? parsed.version : "0.0.0";
|
|
18853
|
+
} catch {
|
|
18854
|
+
return "0.0.0";
|
|
18855
|
+
}
|
|
18856
|
+
}
|
|
18857
|
+
async function planMigration(rootDir, targetVersion) {
|
|
18858
|
+
const fromVersion = await detectVaultVersion(rootDir);
|
|
18859
|
+
const toVersion = targetVersion ?? await currentPackageVersion();
|
|
18860
|
+
const steps = ALL_MIGRATIONS.filter((step) => compareSemver(step.toVersion, toVersion) <= 0).filter((step) => {
|
|
18861
|
+
if (!fromVersion) return true;
|
|
18862
|
+
return compareSemver(step.toVersion, fromVersion) > 0;
|
|
18863
|
+
});
|
|
18864
|
+
return { fromVersion, toVersion, steps };
|
|
18865
|
+
}
|
|
18866
|
+
async function writeVaultVersionRecord(stateDir, record) {
|
|
18867
|
+
await fs16.mkdir(stateDir, { recursive: true });
|
|
18868
|
+
await fs16.writeFile(path17.join(stateDir, VAULT_VERSION_FILENAME), `${JSON.stringify(record, null, 2)}
|
|
18869
|
+
`, "utf8");
|
|
18870
|
+
}
|
|
18871
|
+
async function runMigration(rootDir, options = {}) {
|
|
18872
|
+
const dryRun = options.dryRun ?? true;
|
|
18873
|
+
const { paths } = await initWorkspace(rootDir);
|
|
18874
|
+
const plan = await planMigration(rootDir, options.targetVersion);
|
|
18875
|
+
const applied = [];
|
|
18876
|
+
const skipped = [];
|
|
18877
|
+
const ctx = {
|
|
18878
|
+
rootDir,
|
|
18879
|
+
paths: { wikiDir: paths.wikiDir, stateDir: paths.stateDir, rootDir }
|
|
18880
|
+
};
|
|
18881
|
+
for (const step of plan.steps) {
|
|
18882
|
+
const { changed } = await step.apply(ctx, { dryRun });
|
|
18883
|
+
if (changed.length === 0) {
|
|
18884
|
+
skipped.push({ id: step.id, reason: "No changes required." });
|
|
18885
|
+
} else {
|
|
18886
|
+
applied.push({ id: step.id, changed });
|
|
18887
|
+
}
|
|
18888
|
+
}
|
|
18889
|
+
if (!dryRun && applied.length > 0) {
|
|
18890
|
+
await writeVaultVersionRecord(paths.stateDir, {
|
|
18891
|
+
version: plan.toVersion,
|
|
18892
|
+
migratedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18893
|
+
appliedSteps: applied.map((entry) => entry.id)
|
|
18894
|
+
});
|
|
18895
|
+
}
|
|
18896
|
+
return {
|
|
18897
|
+
planned: plan.steps.length,
|
|
18898
|
+
applied,
|
|
18899
|
+
skipped,
|
|
18900
|
+
dryRun,
|
|
18901
|
+
fromVersion: plan.fromVersion,
|
|
18902
|
+
toVersion: plan.toVersion
|
|
18903
|
+
};
|
|
18904
|
+
}
|
|
18905
|
+
|
|
18906
|
+
// src/schema.ts
|
|
18907
|
+
import fs17 from "fs/promises";
|
|
18908
|
+
import path18 from "path";
|
|
18658
18909
|
function normalizeSchemaContent(content) {
|
|
18659
18910
|
return content.trim() ? content.trim() : defaultVaultSchema().trim();
|
|
18660
18911
|
}
|
|
18661
18912
|
async function readSchemaFile(schemaPath, fallback = defaultVaultSchema()) {
|
|
18662
|
-
const content = await fileExists(schemaPath) ? await
|
|
18913
|
+
const content = await fileExists(schemaPath) ? await fs17.readFile(schemaPath, "utf8") : fallback;
|
|
18663
18914
|
const normalized = normalizeSchemaContent(content);
|
|
18664
18915
|
return {
|
|
18665
18916
|
path: schemaPath,
|
|
@@ -18668,7 +18919,7 @@ async function readSchemaFile(schemaPath, fallback = defaultVaultSchema()) {
|
|
|
18668
18919
|
};
|
|
18669
18920
|
}
|
|
18670
18921
|
function resolveProjectSchemaPath(rootDir, schemaPath) {
|
|
18671
|
-
return
|
|
18922
|
+
return path18.resolve(rootDir, schemaPath);
|
|
18672
18923
|
}
|
|
18673
18924
|
function composeVaultSchema(root, projectSchemas = []) {
|
|
18674
18925
|
if (!projectSchemas.length) {
|
|
@@ -18684,7 +18935,7 @@ function composeVaultSchema(root, projectSchemas = []) {
|
|
|
18684
18935
|
(schema) => [
|
|
18685
18936
|
`## Project Schema`,
|
|
18686
18937
|
"",
|
|
18687
|
-
`Path: ${toPosix(
|
|
18938
|
+
`Path: ${toPosix(path18.relative(path18.dirname(root.path), schema.path) || schema.path)}`,
|
|
18688
18939
|
"",
|
|
18689
18940
|
schema.content
|
|
18690
18941
|
].join("\n")
|
|
@@ -18760,15 +19011,15 @@ function buildSchemaPrompt(schema, instruction) {
|
|
|
18760
19011
|
}
|
|
18761
19012
|
|
|
18762
19013
|
// src/vault.ts
|
|
18763
|
-
import
|
|
18764
|
-
import
|
|
19014
|
+
import fs22 from "fs/promises";
|
|
19015
|
+
import path26 from "path";
|
|
18765
19016
|
import Graph from "graphology";
|
|
18766
19017
|
import louvain from "graphology-communities-louvain";
|
|
18767
|
-
import
|
|
19018
|
+
import matter13 from "gray-matter";
|
|
18768
19019
|
import { z as z7 } from "zod";
|
|
18769
19020
|
|
|
18770
19021
|
// src/analysis.ts
|
|
18771
|
-
import
|
|
19022
|
+
import path19 from "path";
|
|
18772
19023
|
import nlp2 from "compromise";
|
|
18773
19024
|
import { z as z2 } from "zod";
|
|
18774
19025
|
|
|
@@ -18857,7 +19108,7 @@ var MARKDOWN_RATIONALE_KINDS = /* @__PURE__ */ new Set([
|
|
|
18857
19108
|
var PLAIN_TEXT_RATIONALE_KINDS = /* @__PURE__ */ new Set(["text", "transcript", "chat_export", "email", "calendar"]);
|
|
18858
19109
|
function filenameStemForSource(manifest) {
|
|
18859
19110
|
const candidate = manifest.repoRelativePath ?? manifest.originalPath ?? manifest.storedPath;
|
|
18860
|
-
const base =
|
|
19111
|
+
const base = path19.basename(candidate);
|
|
18861
19112
|
const stem = base.replace(/\.[^.]+$/, "");
|
|
18862
19113
|
return stem || manifest.title;
|
|
18863
19114
|
}
|
|
@@ -19137,7 +19388,7 @@ function extractionWarningSummary(manifest, extraction) {
|
|
|
19137
19388
|
return `Imported ${manifest.sourceKind} source. Text extraction is not yet available for this source.`;
|
|
19138
19389
|
}
|
|
19139
19390
|
async function analyzeSource(manifest, extractedText, provider, paths, schema) {
|
|
19140
|
-
const cachePath =
|
|
19391
|
+
const cachePath = path19.join(paths.analysesDir, `${manifest.sourceId}.json`);
|
|
19141
19392
|
const cached = await readJsonFile(cachePath);
|
|
19142
19393
|
if (cached && cached.analysisVersion === ANALYSIS_FORMAT_VERSION && (cached.semanticHash ?? cached.sourceHash) === manifest.semanticHash && cached.extractionHash === manifest.extractionHash && cached.schemaHash === schema.hash) {
|
|
19143
19394
|
const normalizedCached = normalizeSourceAnalysis(manifest, cached);
|
|
@@ -19240,9 +19491,9 @@ function conflictConfidence(claimA, claimB) {
|
|
|
19240
19491
|
}
|
|
19241
19492
|
|
|
19242
19493
|
// src/deep-lint.ts
|
|
19243
|
-
import
|
|
19244
|
-
import
|
|
19245
|
-
import
|
|
19494
|
+
import fs18 from "fs/promises";
|
|
19495
|
+
import path22 from "path";
|
|
19496
|
+
import matter10 from "gray-matter";
|
|
19246
19497
|
import { z as z5 } from "zod";
|
|
19247
19498
|
|
|
19248
19499
|
// src/findings.ts
|
|
@@ -19262,7 +19513,7 @@ function normalizeFindingSeverity(value) {
|
|
|
19262
19513
|
|
|
19263
19514
|
// src/orchestration.ts
|
|
19264
19515
|
import { spawn } from "child_process";
|
|
19265
|
-
import
|
|
19516
|
+
import path20 from "path";
|
|
19266
19517
|
import { z as z3 } from "zod";
|
|
19267
19518
|
var orchestrationRoleResultSchema = z3.object({
|
|
19268
19519
|
summary: z3.string().optional(),
|
|
@@ -19355,7 +19606,7 @@ async function runProviderRole(rootDir, role, roleConfig, input) {
|
|
|
19355
19606
|
}
|
|
19356
19607
|
async function runCommandRole(rootDir, role, executor, input) {
|
|
19357
19608
|
const [command, ...args] = executor.command;
|
|
19358
|
-
const cwd = executor.cwd ?
|
|
19609
|
+
const cwd = executor.cwd ? path20.resolve(rootDir, executor.cwd) : rootDir;
|
|
19359
19610
|
const child = spawn(command, args, {
|
|
19360
19611
|
cwd,
|
|
19361
19612
|
env: {
|
|
@@ -19449,7 +19700,7 @@ function summarizeRoleQuestions(results) {
|
|
|
19449
19700
|
}
|
|
19450
19701
|
|
|
19451
19702
|
// src/web-search/registry.ts
|
|
19452
|
-
import
|
|
19703
|
+
import path21 from "path";
|
|
19453
19704
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
19454
19705
|
import { z as z4 } from "zod";
|
|
19455
19706
|
|
|
@@ -19547,7 +19798,7 @@ async function createWebSearchAdapter(id, config, rootDir) {
|
|
|
19547
19798
|
if (!config.module) {
|
|
19548
19799
|
throw new Error(`Web search provider ${id} is type "custom" but no module path was configured.`);
|
|
19549
19800
|
}
|
|
19550
|
-
const resolvedModule =
|
|
19801
|
+
const resolvedModule = path21.isAbsolute(config.module) ? config.module : path21.resolve(rootDir, config.module);
|
|
19551
19802
|
const loaded = await import(pathToFileURL2(resolvedModule).href);
|
|
19552
19803
|
const parsed = customWebSearchModuleSchema.parse(loaded);
|
|
19553
19804
|
return parsed.createAdapter(id, config, rootDir);
|
|
@@ -19617,9 +19868,9 @@ async function loadContextPages(rootDir, graph) {
|
|
|
19617
19868
|
);
|
|
19618
19869
|
return Promise.all(
|
|
19619
19870
|
contextPages.slice(0, 18).map(async (page) => {
|
|
19620
|
-
const absolutePath =
|
|
19621
|
-
const raw = await
|
|
19622
|
-
const parsed =
|
|
19871
|
+
const absolutePath = path22.join(paths.wikiDir, page.path);
|
|
19872
|
+
const raw = await fs18.readFile(absolutePath, "utf8").catch(() => "");
|
|
19873
|
+
const parsed = matter10(raw);
|
|
19623
19874
|
return {
|
|
19624
19875
|
id: page.id,
|
|
19625
19876
|
title: page.title,
|
|
@@ -19666,7 +19917,7 @@ function heuristicDeepFindings(contextPages, structuralFindings, graph) {
|
|
|
19666
19917
|
code: "missing_citation",
|
|
19667
19918
|
message: finding.message,
|
|
19668
19919
|
pagePath: finding.pagePath,
|
|
19669
|
-
suggestedQuery: finding.pagePath ? `Which sources support the claims in ${
|
|
19920
|
+
suggestedQuery: finding.pagePath ? `Which sources support the claims in ${path22.basename(finding.pagePath, ".md")}?` : void 0
|
|
19670
19921
|
});
|
|
19671
19922
|
}
|
|
19672
19923
|
for (const page of contextPages.filter((item) => item.kind === "source").slice(0, 3)) {
|
|
@@ -20039,9 +20290,9 @@ function buildOutputAssetManifest(input) {
|
|
|
20039
20290
|
}
|
|
20040
20291
|
|
|
20041
20292
|
// src/outputs.ts
|
|
20042
|
-
import
|
|
20043
|
-
import
|
|
20044
|
-
import
|
|
20293
|
+
import fs19 from "fs/promises";
|
|
20294
|
+
import path23 from "path";
|
|
20295
|
+
import matter11 from "gray-matter";
|
|
20045
20296
|
function relationRank(outputPage, targetPage) {
|
|
20046
20297
|
if (outputPage.relatedPageIds.includes(targetPage.id)) {
|
|
20047
20298
|
return 3;
|
|
@@ -20058,19 +20309,19 @@ function relatedOutputsForPage(targetPage, outputPages) {
|
|
|
20058
20309
|
return outputPages.map((page) => ({ page, rank: relationRank(page, targetPage) })).filter((item) => item.rank > 0).sort((left, right) => right.rank - left.rank || left.page.title.localeCompare(right.page.title)).map((item) => item.page);
|
|
20059
20310
|
}
|
|
20060
20311
|
async function resolveUniqueOutputSlug(wikiDir, baseSlug) {
|
|
20061
|
-
const outputsDir =
|
|
20312
|
+
const outputsDir = path23.join(wikiDir, "outputs");
|
|
20062
20313
|
const root = baseSlug || "output";
|
|
20063
20314
|
let candidate = root;
|
|
20064
20315
|
let counter = 2;
|
|
20065
|
-
while (await fileExists(
|
|
20316
|
+
while (await fileExists(path23.join(outputsDir, `${candidate}.md`))) {
|
|
20066
20317
|
candidate = `${root}-${counter}`;
|
|
20067
20318
|
counter++;
|
|
20068
20319
|
}
|
|
20069
20320
|
return candidate;
|
|
20070
20321
|
}
|
|
20071
20322
|
async function loadSavedOutputPages(wikiDir) {
|
|
20072
|
-
const outputsDir =
|
|
20073
|
-
const entries = await
|
|
20323
|
+
const outputsDir = path23.join(wikiDir, "outputs");
|
|
20324
|
+
const entries = await fs19.readdir(outputsDir, { withFileTypes: true }).catch(() => []);
|
|
20074
20325
|
const outputs = [];
|
|
20075
20326
|
const queue = [{ absoluteDir: outputsDir, relativeDir: "outputs" }];
|
|
20076
20327
|
while (queue.length > 0) {
|
|
@@ -20078,24 +20329,24 @@ async function loadSavedOutputPages(wikiDir) {
|
|
|
20078
20329
|
if (!current) {
|
|
20079
20330
|
continue;
|
|
20080
20331
|
}
|
|
20081
|
-
const currentEntries = current.absoluteDir === outputsDir ? entries : await
|
|
20332
|
+
const currentEntries = current.absoluteDir === outputsDir ? entries : await fs19.readdir(current.absoluteDir, { withFileTypes: true }).catch(() => []);
|
|
20082
20333
|
for (const entry of currentEntries) {
|
|
20083
20334
|
if (entry.isDirectory()) {
|
|
20084
20335
|
queue.push({
|
|
20085
|
-
absoluteDir:
|
|
20086
|
-
relativeDir:
|
|
20336
|
+
absoluteDir: path23.join(current.absoluteDir, entry.name),
|
|
20337
|
+
relativeDir: path23.posix.join(current.relativeDir, entry.name)
|
|
20087
20338
|
});
|
|
20088
20339
|
continue;
|
|
20089
20340
|
}
|
|
20090
20341
|
if (!entry.isFile() || !entry.name.endsWith(".md") || entry.name === "index.md") {
|
|
20091
20342
|
continue;
|
|
20092
20343
|
}
|
|
20093
|
-
const relativePath =
|
|
20094
|
-
const absolutePath =
|
|
20095
|
-
const content = await
|
|
20096
|
-
const parsed =
|
|
20344
|
+
const relativePath = path23.posix.join(current.relativeDir, entry.name);
|
|
20345
|
+
const absolutePath = path23.join(current.absoluteDir, entry.name);
|
|
20346
|
+
const content = await fs19.readFile(absolutePath, "utf8");
|
|
20347
|
+
const parsed = matter11(content);
|
|
20097
20348
|
const slug = relativePath.replace(/^outputs\//, "").replace(/\.md$/, "");
|
|
20098
|
-
const title = typeof parsed.data.title === "string" ? parsed.data.title :
|
|
20349
|
+
const title = typeof parsed.data.title === "string" ? parsed.data.title : path23.basename(slug);
|
|
20099
20350
|
const pageId = typeof parsed.data.page_id === "string" ? parsed.data.page_id : `output:${slug}`;
|
|
20100
20351
|
const sourceIds = normalizeStringArray(parsed.data.source_ids);
|
|
20101
20352
|
const projectIds = normalizeProjectIds(parsed.data.project_ids);
|
|
@@ -20105,7 +20356,7 @@ async function loadSavedOutputPages(wikiDir) {
|
|
|
20105
20356
|
const relatedSourceIds = normalizeStringArray(parsed.data.related_source_ids);
|
|
20106
20357
|
const backlinks = normalizeStringArray(parsed.data.backlinks);
|
|
20107
20358
|
const compiledFrom = normalizeStringArray(parsed.data.compiled_from);
|
|
20108
|
-
const stats = await
|
|
20359
|
+
const stats = await fs19.stat(absolutePath);
|
|
20109
20360
|
const createdAt = typeof parsed.data.created_at === "string" ? parsed.data.created_at : stats.birthtimeMs > 0 ? stats.birthtime.toISOString() : stats.mtime.toISOString();
|
|
20110
20361
|
const updatedAt = typeof parsed.data.updated_at === "string" ? parsed.data.updated_at : stats.mtime.toISOString();
|
|
20111
20362
|
outputs.push({
|
|
@@ -20145,9 +20396,9 @@ async function loadSavedOutputPages(wikiDir) {
|
|
|
20145
20396
|
}
|
|
20146
20397
|
|
|
20147
20398
|
// src/search.ts
|
|
20148
|
-
import
|
|
20149
|
-
import
|
|
20150
|
-
import
|
|
20399
|
+
import fs20 from "fs/promises";
|
|
20400
|
+
import path24 from "path";
|
|
20401
|
+
import matter12 from "gray-matter";
|
|
20151
20402
|
function warningMessage(warning) {
|
|
20152
20403
|
return warning instanceof Error ? warning.message : String(warning);
|
|
20153
20404
|
}
|
|
@@ -20200,7 +20451,7 @@ function normalizeSourceClass2(value) {
|
|
|
20200
20451
|
return value === "first_party" || value === "third_party" || value === "resource" || value === "generated" ? value : void 0;
|
|
20201
20452
|
}
|
|
20202
20453
|
async function rebuildSearchIndex(dbPath, pages, wikiDir) {
|
|
20203
|
-
await ensureDir(
|
|
20454
|
+
await ensureDir(path24.dirname(dbPath));
|
|
20204
20455
|
const DatabaseSync = getDatabaseSync();
|
|
20205
20456
|
const db = withSuppressedSqliteExperimentalWarning(() => new DatabaseSync(dbPath));
|
|
20206
20457
|
db.exec("PRAGMA journal_mode = WAL;");
|
|
@@ -20231,21 +20482,21 @@ async function rebuildSearchIndex(dbPath, pages, wikiDir) {
|
|
|
20231
20482
|
const insertPage = db.prepare(
|
|
20232
20483
|
"INSERT INTO pages (id, path, title, body, kind, status, source_type, source_class, project_ids, project_key) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
|
20233
20484
|
);
|
|
20234
|
-
const rootDir =
|
|
20485
|
+
const rootDir = path24.dirname(wikiDir);
|
|
20235
20486
|
for (const page of pages) {
|
|
20236
|
-
const absolutePath =
|
|
20237
|
-
const content = await
|
|
20238
|
-
const parsed =
|
|
20487
|
+
const absolutePath = path24.join(wikiDir, page.path);
|
|
20488
|
+
const content = await fs20.readFile(absolutePath, "utf8");
|
|
20489
|
+
const parsed = matter12(content);
|
|
20239
20490
|
let body = parsed.content;
|
|
20240
20491
|
const primarySourceId = Array.isArray(parsed.data.source_ids) && typeof parsed.data.source_ids[0] === "string" ? parsed.data.source_ids[0] : page.sourceIds[0];
|
|
20241
20492
|
if ((page.kind === "source" || page.kind === "module") && primarySourceId) {
|
|
20242
20493
|
try {
|
|
20243
20494
|
const manifest = JSON.parse(
|
|
20244
|
-
await
|
|
20495
|
+
await fs20.readFile(path24.join(rootDir, "state", "manifests", `${primarySourceId}.json`), "utf8")
|
|
20245
20496
|
);
|
|
20246
20497
|
const excerptPath = manifest.extractedTextPath ?? manifest.storedPath;
|
|
20247
20498
|
if (excerptPath) {
|
|
20248
|
-
const excerpt = await
|
|
20499
|
+
const excerpt = await fs20.readFile(path24.join(rootDir, excerptPath), "utf8");
|
|
20249
20500
|
if (excerpt.trim()) {
|
|
20250
20501
|
body = `${body}
|
|
20251
20502
|
|
|
@@ -20401,16 +20652,16 @@ function searchPages(dbPath, query, limitOrOptions = 5) {
|
|
|
20401
20652
|
}
|
|
20402
20653
|
|
|
20403
20654
|
// src/source-sessions.ts
|
|
20404
|
-
import
|
|
20405
|
-
import
|
|
20655
|
+
import fs21 from "fs/promises";
|
|
20656
|
+
import path25 from "path";
|
|
20406
20657
|
function sessionStatePathFor(paths, sessionId) {
|
|
20407
|
-
return
|
|
20658
|
+
return path25.join(paths.sourceSessionsDir, `${sessionId}.json`);
|
|
20408
20659
|
}
|
|
20409
20660
|
async function listGuidedSourceSessions(rootDir) {
|
|
20410
20661
|
const { paths } = await loadVaultConfig(rootDir);
|
|
20411
|
-
const entries = await
|
|
20662
|
+
const entries = await fs21.readdir(paths.sourceSessionsDir, { withFileTypes: true }).catch(() => []);
|
|
20412
20663
|
const sessions = await Promise.all(
|
|
20413
|
-
entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map(async (entry) => await readJsonFile(
|
|
20664
|
+
entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map(async (entry) => await readJsonFile(path25.join(paths.sourceSessionsDir, entry.name)))
|
|
20414
20665
|
);
|
|
20415
20666
|
return sessions.filter((session) => Boolean(session)).sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
|
|
20416
20667
|
}
|
|
@@ -20430,7 +20681,7 @@ async function writeGuidedSourceSession(rootDir, session) {
|
|
|
20430
20681
|
updatedAt: session.updatedAt || (/* @__PURE__ */ new Date()).toISOString()
|
|
20431
20682
|
};
|
|
20432
20683
|
const filePath = sessionStatePathFor(paths, session.sessionId);
|
|
20433
|
-
await
|
|
20684
|
+
await fs21.writeFile(filePath, `${JSON.stringify(next, null, 2)}
|
|
20434
20685
|
`, "utf8");
|
|
20435
20686
|
return filePath;
|
|
20436
20687
|
}
|
|
@@ -20506,7 +20757,7 @@ function outputFormatInstruction(format) {
|
|
|
20506
20757
|
}
|
|
20507
20758
|
}
|
|
20508
20759
|
function outputAssetPath(slug, fileName) {
|
|
20509
|
-
return toPosix(
|
|
20760
|
+
return toPosix(path26.join("outputs", "assets", slug, fileName));
|
|
20510
20761
|
}
|
|
20511
20762
|
function outputAssetId(slug, role) {
|
|
20512
20763
|
return `output:${slug}:asset:${role}`;
|
|
@@ -20844,7 +21095,7 @@ async function generateOutputArtifacts(rootDir, input) {
|
|
|
20844
21095
|
};
|
|
20845
21096
|
}
|
|
20846
21097
|
function normalizeProjectRoot(root) {
|
|
20847
|
-
const normalized = toPosix(
|
|
21098
|
+
const normalized = toPosix(path26.posix.normalize(root.replace(/\\/g, "/"))).replace(/^\.\/+/, "").replace(/\/+$/, "");
|
|
20848
21099
|
return normalized;
|
|
20849
21100
|
}
|
|
20850
21101
|
function projectEntries(config) {
|
|
@@ -20870,10 +21121,10 @@ function manifestPathForProject(rootDir, manifest) {
|
|
|
20870
21121
|
if (!rawPath) {
|
|
20871
21122
|
return toPosix(manifest.storedPath);
|
|
20872
21123
|
}
|
|
20873
|
-
if (!
|
|
21124
|
+
if (!path26.isAbsolute(rawPath)) {
|
|
20874
21125
|
return normalizeProjectRoot(rawPath);
|
|
20875
21126
|
}
|
|
20876
|
-
const relative = toPosix(
|
|
21127
|
+
const relative = toPosix(path26.relative(rootDir, rawPath));
|
|
20877
21128
|
return relative.startsWith("..") ? toPosix(rawPath) : normalizeProjectRoot(relative);
|
|
20878
21129
|
}
|
|
20879
21130
|
function prefixMatches(value, prefix) {
|
|
@@ -21050,7 +21301,7 @@ function pageHashes(pages) {
|
|
|
21050
21301
|
return Object.fromEntries(pages.map((page) => [page.page.id, page.contentHash]));
|
|
21051
21302
|
}
|
|
21052
21303
|
async function buildManagedGraphPage(absolutePath, defaults, build) {
|
|
21053
|
-
const existingContent = await fileExists(absolutePath) ? await
|
|
21304
|
+
const existingContent = await fileExists(absolutePath) ? await fs22.readFile(absolutePath, "utf8") : null;
|
|
21054
21305
|
let carriedContent = existingContent;
|
|
21055
21306
|
let existing = await loadExistingManagedPageState(absolutePath, {
|
|
21056
21307
|
status: defaults.status ?? "active",
|
|
@@ -21066,7 +21317,7 @@ async function buildManagedGraphPage(absolutePath, defaults, build) {
|
|
|
21066
21317
|
status: defaults.status ?? "active",
|
|
21067
21318
|
managedBy: defaults.managedBy
|
|
21068
21319
|
});
|
|
21069
|
-
carriedContent = await
|
|
21320
|
+
carriedContent = await fs22.readFile(candidatePath, "utf8");
|
|
21070
21321
|
usedFallbackState = true;
|
|
21071
21322
|
break;
|
|
21072
21323
|
}
|
|
@@ -21090,7 +21341,7 @@ async function buildManagedGraphPage(absolutePath, defaults, build) {
|
|
|
21090
21341
|
return built;
|
|
21091
21342
|
}
|
|
21092
21343
|
async function buildManagedContent(absolutePath, defaults, build) {
|
|
21093
|
-
const existingContent = await fileExists(absolutePath) ? await
|
|
21344
|
+
const existingContent = await fileExists(absolutePath) ? await fs22.readFile(absolutePath, "utf8") : null;
|
|
21094
21345
|
let existing = await loadExistingManagedPageState(absolutePath, {
|
|
21095
21346
|
status: defaults.status ?? "active",
|
|
21096
21347
|
managedBy: defaults.managedBy
|
|
@@ -21132,7 +21383,7 @@ function manifestDetailValue(manifest, key) {
|
|
|
21132
21383
|
}
|
|
21133
21384
|
async function loadAnalysesBySourceIds(paths, sourceIds) {
|
|
21134
21385
|
const analyses = await Promise.all(
|
|
21135
|
-
sourceIds.map(async (sourceId) => await readJsonFile(
|
|
21386
|
+
sourceIds.map(async (sourceId) => await readJsonFile(path26.join(paths.analysesDir, `${sourceId}.json`)))
|
|
21136
21387
|
);
|
|
21137
21388
|
return analyses.filter((analysis) => Boolean(analysis?.sourceId));
|
|
21138
21389
|
}
|
|
@@ -21157,7 +21408,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
21157
21408
|
).slice(0, 20);
|
|
21158
21409
|
const sourceSessions = await listGuidedSourceSessions(paths.rootDir);
|
|
21159
21410
|
const stagedGuideBundles = (await Promise.all(
|
|
21160
|
-
(await
|
|
21411
|
+
(await fs22.readdir(paths.approvalsDir, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory()).map(async (entry) => await readApprovalManifest(paths, entry.name).catch(() => null))
|
|
21161
21412
|
)).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);
|
|
21162
21413
|
const readerFocusPages = uniqueBy([...guidePages, ...briefPages, ...conceptPages, ...entityPages], (page) => page.id).slice(0, 8);
|
|
21163
21414
|
const diligenceSessions = sourceSessions.filter((session) => session.status === "staged" || session.status === "awaiting_input").slice(0, 8);
|
|
@@ -21165,7 +21416,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
21165
21416
|
{
|
|
21166
21417
|
relativePath: "dashboards/index.md",
|
|
21167
21418
|
title: "Dashboards",
|
|
21168
|
-
content: (metadata) =>
|
|
21419
|
+
content: (metadata) => matter13.stringify(
|
|
21169
21420
|
[
|
|
21170
21421
|
"# Dashboards",
|
|
21171
21422
|
"",
|
|
@@ -21217,7 +21468,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
21217
21468
|
{
|
|
21218
21469
|
relativePath: "dashboards/recent-sources.md",
|
|
21219
21470
|
title: "Recent Sources",
|
|
21220
|
-
content: (metadata) =>
|
|
21471
|
+
content: (metadata) => matter13.stringify(
|
|
21221
21472
|
[
|
|
21222
21473
|
"# Recent Sources",
|
|
21223
21474
|
"",
|
|
@@ -21260,7 +21511,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
21260
21511
|
{
|
|
21261
21512
|
relativePath: "dashboards/reading-log.md",
|
|
21262
21513
|
title: "Reading Log",
|
|
21263
|
-
content: (metadata) =>
|
|
21514
|
+
content: (metadata) => matter13.stringify(
|
|
21264
21515
|
[
|
|
21265
21516
|
"# Reading Log",
|
|
21266
21517
|
"",
|
|
@@ -21320,7 +21571,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
21320
21571
|
{
|
|
21321
21572
|
relativePath: "dashboards/timeline.md",
|
|
21322
21573
|
title: "Timeline",
|
|
21323
|
-
content: (metadata) =>
|
|
21574
|
+
content: (metadata) => matter13.stringify(
|
|
21324
21575
|
[
|
|
21325
21576
|
"# Timeline",
|
|
21326
21577
|
"",
|
|
@@ -21366,7 +21617,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
21366
21617
|
{
|
|
21367
21618
|
relativePath: "dashboards/source-sessions.md",
|
|
21368
21619
|
title: "Source Sessions",
|
|
21369
|
-
content: (metadata) =>
|
|
21620
|
+
content: (metadata) => matter13.stringify(
|
|
21370
21621
|
[
|
|
21371
21622
|
"# Source Sessions",
|
|
21372
21623
|
"",
|
|
@@ -21423,7 +21674,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
21423
21674
|
{
|
|
21424
21675
|
relativePath: "dashboards/source-guides.md",
|
|
21425
21676
|
title: "Source Guides",
|
|
21426
|
-
content: (metadata) =>
|
|
21677
|
+
content: (metadata) => matter13.stringify(
|
|
21427
21678
|
[
|
|
21428
21679
|
"# Source Guides",
|
|
21429
21680
|
"",
|
|
@@ -21476,7 +21727,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
21476
21727
|
{
|
|
21477
21728
|
relativePath: "dashboards/research-map.md",
|
|
21478
21729
|
title: "Research Map",
|
|
21479
|
-
content: (metadata) =>
|
|
21730
|
+
content: (metadata) => matter13.stringify(
|
|
21480
21731
|
[
|
|
21481
21732
|
"# Research Map",
|
|
21482
21733
|
"",
|
|
@@ -21540,7 +21791,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
21540
21791
|
{
|
|
21541
21792
|
relativePath: "dashboards/contradictions.md",
|
|
21542
21793
|
title: "Contradictions",
|
|
21543
|
-
content: (metadata) =>
|
|
21794
|
+
content: (metadata) => matter13.stringify(
|
|
21544
21795
|
[
|
|
21545
21796
|
"# Contradictions",
|
|
21546
21797
|
"",
|
|
@@ -21599,7 +21850,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
21599
21850
|
{
|
|
21600
21851
|
relativePath: "dashboards/open-questions.md",
|
|
21601
21852
|
title: "Open Questions",
|
|
21602
|
-
content: (metadata) =>
|
|
21853
|
+
content: (metadata) => matter13.stringify(
|
|
21603
21854
|
[
|
|
21604
21855
|
"# Open Questions",
|
|
21605
21856
|
"",
|
|
@@ -21645,7 +21896,7 @@ async function buildDashboardRecords(config, paths, graph, schemaHash, report) {
|
|
|
21645
21896
|
];
|
|
21646
21897
|
const records = [];
|
|
21647
21898
|
for (const dashboard of dashboards) {
|
|
21648
|
-
const absolutePath =
|
|
21899
|
+
const absolutePath = path26.join(paths.wikiDir, dashboard.relativePath);
|
|
21649
21900
|
const compiledFrom = dashboard.relativePath === "dashboards/recent-sources.md" ? recentSourcePages.flatMap((page) => page.sourceIds) : [];
|
|
21650
21901
|
const content = await buildManagedContent(
|
|
21651
21902
|
absolutePath,
|
|
@@ -21808,7 +22059,7 @@ function resetGraphNodeMetrics(nodes) {
|
|
|
21808
22059
|
);
|
|
21809
22060
|
}
|
|
21810
22061
|
function manifestRepoPath(manifest) {
|
|
21811
|
-
return toPosix(manifest.repoRelativePath ??
|
|
22062
|
+
return toPosix(manifest.repoRelativePath ?? path26.basename(manifest.originalPath ?? manifest.storedPath));
|
|
21812
22063
|
}
|
|
21813
22064
|
function goPackageScopeKey(manifest, analysis) {
|
|
21814
22065
|
if (analysis.code?.language !== "go") {
|
|
@@ -21818,7 +22069,7 @@ function goPackageScopeKey(manifest, analysis) {
|
|
|
21818
22069
|
if (!packageName) {
|
|
21819
22070
|
return null;
|
|
21820
22071
|
}
|
|
21821
|
-
return `${packageName}:${
|
|
22072
|
+
return `${packageName}:${path26.posix.dirname(manifestRepoPath(manifest))}`;
|
|
21822
22073
|
}
|
|
21823
22074
|
function buildGoPackageSymbolLookups(analyses, manifestsById) {
|
|
21824
22075
|
const lookups = /* @__PURE__ */ new Map();
|
|
@@ -22343,7 +22594,7 @@ async function buildGraphOrientationPages(graph, paths, schemaHash, previousComp
|
|
|
22343
22594
|
const benchmark = await readJsonFile(paths.benchmarkPath);
|
|
22344
22595
|
const communityRecords = [];
|
|
22345
22596
|
for (const community of graph.communities ?? []) {
|
|
22346
|
-
const absolutePath =
|
|
22597
|
+
const absolutePath = path26.join(paths.wikiDir, "graph", "communities", `${community.id.replace(/^community:/, "")}.md`);
|
|
22347
22598
|
communityRecords.push(
|
|
22348
22599
|
await buildManagedGraphPage(
|
|
22349
22600
|
absolutePath,
|
|
@@ -22373,7 +22624,7 @@ async function buildGraphOrientationPages(graph, paths, schemaHash, previousComp
|
|
|
22373
22624
|
contradictions,
|
|
22374
22625
|
config
|
|
22375
22626
|
});
|
|
22376
|
-
const reportAbsolutePath =
|
|
22627
|
+
const reportAbsolutePath = path26.join(paths.wikiDir, "graph", "report.md");
|
|
22377
22628
|
const reportRecord = await buildManagedGraphPage(
|
|
22378
22629
|
reportAbsolutePath,
|
|
22379
22630
|
{
|
|
@@ -22394,7 +22645,7 @@ async function buildGraphOrientationPages(graph, paths, schemaHash, previousComp
|
|
|
22394
22645
|
};
|
|
22395
22646
|
}
|
|
22396
22647
|
async function writePage(wikiDir, relativePath, content, changedPages) {
|
|
22397
|
-
const absolutePath =
|
|
22648
|
+
const absolutePath = path26.resolve(wikiDir, relativePath);
|
|
22398
22649
|
const changed = await writeFileIfChanged(absolutePath, content);
|
|
22399
22650
|
if (changed) {
|
|
22400
22651
|
changedPages.push(relativePath);
|
|
@@ -22460,29 +22711,29 @@ async function requiredCompileArtifactsExist(paths) {
|
|
|
22460
22711
|
paths.graphPath,
|
|
22461
22712
|
paths.codeIndexPath,
|
|
22462
22713
|
paths.searchDbPath,
|
|
22463
|
-
|
|
22464
|
-
|
|
22465
|
-
|
|
22466
|
-
|
|
22467
|
-
|
|
22468
|
-
|
|
22469
|
-
|
|
22470
|
-
|
|
22714
|
+
path26.join(paths.wikiDir, "index.md"),
|
|
22715
|
+
path26.join(paths.wikiDir, "sources", "index.md"),
|
|
22716
|
+
path26.join(paths.wikiDir, "code", "index.md"),
|
|
22717
|
+
path26.join(paths.wikiDir, "concepts", "index.md"),
|
|
22718
|
+
path26.join(paths.wikiDir, "entities", "index.md"),
|
|
22719
|
+
path26.join(paths.wikiDir, "outputs", "index.md"),
|
|
22720
|
+
path26.join(paths.wikiDir, "projects", "index.md"),
|
|
22721
|
+
path26.join(paths.wikiDir, "candidates", "index.md")
|
|
22471
22722
|
];
|
|
22472
22723
|
const checks = await Promise.all(requiredPaths.map((filePath) => fileExists(filePath)));
|
|
22473
22724
|
return checks.every(Boolean);
|
|
22474
22725
|
}
|
|
22475
22726
|
async function loadAvailableCachedAnalyses(paths, manifests) {
|
|
22476
22727
|
const analyses = await Promise.all(
|
|
22477
|
-
manifests.map(async (manifest) => readJsonFile(
|
|
22728
|
+
manifests.map(async (manifest) => readJsonFile(path26.join(paths.analysesDir, `${manifest.sourceId}.json`)))
|
|
22478
22729
|
);
|
|
22479
22730
|
return analyses.filter((analysis) => Boolean(analysis));
|
|
22480
22731
|
}
|
|
22481
22732
|
function approvalManifestPath(paths, approvalId) {
|
|
22482
|
-
return
|
|
22733
|
+
return path26.join(paths.approvalsDir, approvalId, "manifest.json");
|
|
22483
22734
|
}
|
|
22484
22735
|
function approvalGraphPath(paths, approvalId) {
|
|
22485
|
-
return
|
|
22736
|
+
return path26.join(paths.approvalsDir, approvalId, "state", "graph.json");
|
|
22486
22737
|
}
|
|
22487
22738
|
function normalizeApprovalBundleType(raw) {
|
|
22488
22739
|
if (!raw) return void 0;
|
|
@@ -22503,7 +22754,7 @@ async function readApprovalManifest(paths, approvalId) {
|
|
|
22503
22754
|
return manifest;
|
|
22504
22755
|
}
|
|
22505
22756
|
async function writeApprovalManifest(paths, manifest) {
|
|
22506
|
-
await
|
|
22757
|
+
await fs22.writeFile(approvalManifestPath(paths, manifest.approvalId), `${JSON.stringify(manifest, null, 2)}
|
|
22507
22758
|
`, "utf8");
|
|
22508
22759
|
}
|
|
22509
22760
|
async function buildApprovalEntries(paths, changedFiles, deletedPaths, previousGraph, graph, labelsByPath = /* @__PURE__ */ new Map()) {
|
|
@@ -22518,7 +22769,7 @@ async function buildApprovalEntries(paths, changedFiles, deletedPaths, previousG
|
|
|
22518
22769
|
continue;
|
|
22519
22770
|
}
|
|
22520
22771
|
const previousPage = previousPagesById.get(nextPage.id);
|
|
22521
|
-
const currentExists = await fileExists(
|
|
22772
|
+
const currentExists = await fileExists(path26.join(paths.wikiDir, file.relativePath));
|
|
22522
22773
|
if (previousPage && previousPage.path !== nextPage.path) {
|
|
22523
22774
|
entries.push({
|
|
22524
22775
|
pageId: nextPage.id,
|
|
@@ -22553,7 +22804,7 @@ async function buildApprovalEntries(paths, changedFiles, deletedPaths, previousG
|
|
|
22553
22804
|
const previousPage = previousPagesByPath.get(deletedPath);
|
|
22554
22805
|
entries.push({
|
|
22555
22806
|
pageId: previousPage?.id ?? `page:${slugify(deletedPath)}`,
|
|
22556
|
-
title: previousPage?.title ??
|
|
22807
|
+
title: previousPage?.title ?? path26.basename(deletedPath, ".md"),
|
|
22557
22808
|
kind: previousPage?.kind ?? "index",
|
|
22558
22809
|
changeType: "delete",
|
|
22559
22810
|
status: "pending",
|
|
@@ -22566,16 +22817,16 @@ async function buildApprovalEntries(paths, changedFiles, deletedPaths, previousG
|
|
|
22566
22817
|
}
|
|
22567
22818
|
async function stageApprovalBundle(paths, changedFiles, deletedPaths, previousGraph, graph) {
|
|
22568
22819
|
const approvalId = `compile-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
|
|
22569
|
-
const approvalDir =
|
|
22820
|
+
const approvalDir = path26.join(paths.approvalsDir, approvalId);
|
|
22570
22821
|
await ensureDir(approvalDir);
|
|
22571
|
-
await ensureDir(
|
|
22572
|
-
await ensureDir(
|
|
22822
|
+
await ensureDir(path26.join(approvalDir, "wiki"));
|
|
22823
|
+
await ensureDir(path26.join(approvalDir, "state"));
|
|
22573
22824
|
for (const file of changedFiles) {
|
|
22574
|
-
const targetPath =
|
|
22575
|
-
await ensureDir(
|
|
22576
|
-
await
|
|
22825
|
+
const targetPath = path26.join(approvalDir, "wiki", file.relativePath);
|
|
22826
|
+
await ensureDir(path26.dirname(targetPath));
|
|
22827
|
+
await fs22.writeFile(targetPath, file.content, "utf8");
|
|
22577
22828
|
}
|
|
22578
|
-
await
|
|
22829
|
+
await fs22.writeFile(path26.join(approvalDir, "state", "graph.json"), JSON.stringify(graph, null, 2), "utf8");
|
|
22579
22830
|
await writeApprovalManifest(paths, {
|
|
22580
22831
|
approvalId,
|
|
22581
22832
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -22641,7 +22892,7 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
22641
22892
|
confidence: 1
|
|
22642
22893
|
});
|
|
22643
22894
|
const sourceRecord = await buildManagedGraphPage(
|
|
22644
|
-
|
|
22895
|
+
path26.join(paths.wikiDir, preview.path),
|
|
22645
22896
|
{
|
|
22646
22897
|
managedBy: "system",
|
|
22647
22898
|
confidence: 1,
|
|
@@ -22688,7 +22939,7 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
22688
22939
|
);
|
|
22689
22940
|
records.push(
|
|
22690
22941
|
await buildManagedGraphPage(
|
|
22691
|
-
|
|
22942
|
+
path26.join(paths.wikiDir, modulePreview.path),
|
|
22692
22943
|
{
|
|
22693
22944
|
managedBy: "system",
|
|
22694
22945
|
confidence: 1,
|
|
@@ -22722,8 +22973,8 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
22722
22973
|
const relativePath = promoted ? activeAggregatePath(itemKind, slug) : candidatePagePathFor(itemKind, slug);
|
|
22723
22974
|
const aggregateSourceClass2 = aggregateManifestSourceClass(input.manifests, sourceIds);
|
|
22724
22975
|
const fallbackPaths = [
|
|
22725
|
-
|
|
22726
|
-
|
|
22976
|
+
path26.join(paths.wikiDir, activeAggregatePath(itemKind, slug)),
|
|
22977
|
+
path26.join(paths.wikiDir, candidatePagePathFor(itemKind, slug))
|
|
22727
22978
|
];
|
|
22728
22979
|
const confidence = nodeConfidence(aggregate.sourceAnalyses.length);
|
|
22729
22980
|
const preview = emptyGraphPage({
|
|
@@ -22741,7 +22992,7 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
22741
22992
|
status: promoted ? "active" : "candidate"
|
|
22742
22993
|
});
|
|
22743
22994
|
const pageRecord = await buildManagedGraphPage(
|
|
22744
|
-
|
|
22995
|
+
path26.join(paths.wikiDir, relativePath),
|
|
22745
22996
|
{
|
|
22746
22997
|
status: promoted ? "active" : "candidate",
|
|
22747
22998
|
managedBy: "system",
|
|
@@ -22878,7 +23129,7 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
22878
23129
|
confidence: 1
|
|
22879
23130
|
}),
|
|
22880
23131
|
content: await buildManagedContent(
|
|
22881
|
-
|
|
23132
|
+
path26.join(paths.wikiDir, "projects", "index.md"),
|
|
22882
23133
|
{
|
|
22883
23134
|
managedBy: "system",
|
|
22884
23135
|
compiledFrom: indexCompiledFrom(projectIndexRefs)
|
|
@@ -22902,7 +23153,7 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
22902
23153
|
records.push({
|
|
22903
23154
|
page: projectIndexRef,
|
|
22904
23155
|
content: await buildManagedContent(
|
|
22905
|
-
|
|
23156
|
+
path26.join(paths.wikiDir, projectIndexRef.path),
|
|
22906
23157
|
{
|
|
22907
23158
|
managedBy: "system",
|
|
22908
23159
|
compiledFrom: indexCompiledFrom(Object.values(sections).flat())
|
|
@@ -22930,7 +23181,7 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
22930
23181
|
confidence: 1
|
|
22931
23182
|
}),
|
|
22932
23183
|
content: await buildManagedContent(
|
|
22933
|
-
|
|
23184
|
+
path26.join(paths.wikiDir, "index.md"),
|
|
22934
23185
|
{
|
|
22935
23186
|
managedBy: "system",
|
|
22936
23187
|
compiledFrom: indexCompiledFrom(allPages)
|
|
@@ -22966,7 +23217,7 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
22966
23217
|
confidence: 1
|
|
22967
23218
|
}),
|
|
22968
23219
|
content: await buildManagedContent(
|
|
22969
|
-
|
|
23220
|
+
path26.join(paths.wikiDir, relativePath),
|
|
22970
23221
|
{
|
|
22971
23222
|
managedBy: "system",
|
|
22972
23223
|
compiledFrom: indexCompiledFrom(pages)
|
|
@@ -22977,12 +23228,12 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
22977
23228
|
}
|
|
22978
23229
|
const nextPagePaths = new Set(records.map((record) => record.page.path));
|
|
22979
23230
|
const obsoleteGraphPaths = (previousGraph?.pages ?? []).filter((page) => page.kind !== "output" && page.kind !== "insight").map((page) => page.path).filter((relativePath) => !nextPagePaths.has(relativePath));
|
|
22980
|
-
const existingProjectIndexPaths = (await listFilesRecursive(paths.projectsDir)).filter((absolutePath) => absolutePath.endsWith(".md")).map((absolutePath) => toPosix(
|
|
23231
|
+
const existingProjectIndexPaths = (await listFilesRecursive(paths.projectsDir)).filter((absolutePath) => absolutePath.endsWith(".md")).map((absolutePath) => toPosix(path26.relative(paths.wikiDir, absolutePath))).filter((relativePath) => !nextPagePaths.has(relativePath));
|
|
22981
23232
|
const obsoletePaths = uniqueStrings4([...obsoleteGraphPaths, ...existingProjectIndexPaths]);
|
|
22982
23233
|
const changedFiles = [];
|
|
22983
23234
|
for (const record of records) {
|
|
22984
|
-
const absolutePath =
|
|
22985
|
-
const current = await fileExists(absolutePath) ? await
|
|
23235
|
+
const absolutePath = path26.join(paths.wikiDir, record.page.path);
|
|
23236
|
+
const current = await fileExists(absolutePath) ? await fs22.readFile(absolutePath, "utf8") : null;
|
|
22986
23237
|
if (current !== record.content) {
|
|
22987
23238
|
changedPages.push(record.page.path);
|
|
22988
23239
|
changedFiles.push({ relativePath: record.page.path, content: record.content });
|
|
@@ -23007,10 +23258,10 @@ async function syncVaultArtifacts(rootDir, input) {
|
|
|
23007
23258
|
await writePage(paths.wikiDir, record.page.path, record.content, writeChanges);
|
|
23008
23259
|
}
|
|
23009
23260
|
for (const relativePath of obsoletePaths) {
|
|
23010
|
-
await
|
|
23261
|
+
await fs22.rm(path26.join(paths.wikiDir, relativePath), { force: true });
|
|
23011
23262
|
}
|
|
23012
23263
|
await writeJsonFile(paths.graphPath, graph);
|
|
23013
|
-
await writeJsonFile(
|
|
23264
|
+
await writeJsonFile(path26.join(paths.wikiDir, "graph", "report.json"), graphOrientation.report);
|
|
23014
23265
|
await writeJsonFile(paths.codeIndexPath, input.codeIndex);
|
|
23015
23266
|
await writeJsonFile(paths.compileStatePath, {
|
|
23016
23267
|
generatedAt: graph.generatedAt,
|
|
@@ -23108,18 +23359,18 @@ async function refreshIndexesAndSearch(rootDir, pages) {
|
|
|
23108
23359
|
})
|
|
23109
23360
|
);
|
|
23110
23361
|
await Promise.all([
|
|
23111
|
-
ensureDir(
|
|
23112
|
-
ensureDir(
|
|
23113
|
-
ensureDir(
|
|
23114
|
-
ensureDir(
|
|
23115
|
-
ensureDir(
|
|
23116
|
-
ensureDir(
|
|
23117
|
-
ensureDir(
|
|
23118
|
-
ensureDir(
|
|
23119
|
-
ensureDir(
|
|
23120
|
-
ensureDir(
|
|
23362
|
+
ensureDir(path26.join(paths.wikiDir, "sources")),
|
|
23363
|
+
ensureDir(path26.join(paths.wikiDir, "code")),
|
|
23364
|
+
ensureDir(path26.join(paths.wikiDir, "concepts")),
|
|
23365
|
+
ensureDir(path26.join(paths.wikiDir, "entities")),
|
|
23366
|
+
ensureDir(path26.join(paths.wikiDir, "outputs")),
|
|
23367
|
+
ensureDir(path26.join(paths.wikiDir, "dashboards")),
|
|
23368
|
+
ensureDir(path26.join(paths.wikiDir, "graph")),
|
|
23369
|
+
ensureDir(path26.join(paths.wikiDir, "graph", "communities")),
|
|
23370
|
+
ensureDir(path26.join(paths.wikiDir, "projects")),
|
|
23371
|
+
ensureDir(path26.join(paths.wikiDir, "candidates"))
|
|
23121
23372
|
]);
|
|
23122
|
-
const projectsIndexPath =
|
|
23373
|
+
const projectsIndexPath = path26.join(paths.wikiDir, "projects", "index.md");
|
|
23123
23374
|
await writeFileIfChanged(
|
|
23124
23375
|
projectsIndexPath,
|
|
23125
23376
|
await buildManagedContent(
|
|
@@ -23140,7 +23391,7 @@ async function refreshIndexesAndSearch(rootDir, pages) {
|
|
|
23140
23391
|
outputs: pages.filter((page) => page.kind === "output" && page.projectIds.includes(project.id)),
|
|
23141
23392
|
candidates: pages.filter((page) => page.status === "candidate" && page.projectIds.includes(project.id))
|
|
23142
23393
|
};
|
|
23143
|
-
const absolutePath =
|
|
23394
|
+
const absolutePath = path26.join(paths.wikiDir, "projects", project.id, "index.md");
|
|
23144
23395
|
await writeFileIfChanged(
|
|
23145
23396
|
absolutePath,
|
|
23146
23397
|
await buildManagedContent(
|
|
@@ -23158,7 +23409,7 @@ async function refreshIndexesAndSearch(rootDir, pages) {
|
|
|
23158
23409
|
)
|
|
23159
23410
|
);
|
|
23160
23411
|
}
|
|
23161
|
-
const rootIndexPath =
|
|
23412
|
+
const rootIndexPath = path26.join(paths.wikiDir, "index.md");
|
|
23162
23413
|
await writeFileIfChanged(
|
|
23163
23414
|
rootIndexPath,
|
|
23164
23415
|
await buildManagedContent(
|
|
@@ -23184,7 +23435,7 @@ async function refreshIndexesAndSearch(rootDir, pages) {
|
|
|
23184
23435
|
["candidates/index.md", "candidates", pagesWithGraph.filter((page) => page.status === "candidate")],
|
|
23185
23436
|
["graph/index.md", "graph", pagesWithGraph.filter((page) => page.kind === "graph_report" || page.kind === "community_summary")]
|
|
23186
23437
|
]) {
|
|
23187
|
-
const absolutePath =
|
|
23438
|
+
const absolutePath = path26.join(paths.wikiDir, relativePath);
|
|
23188
23439
|
await writeFileIfChanged(
|
|
23189
23440
|
absolutePath,
|
|
23190
23441
|
await buildManagedContent(
|
|
@@ -23198,31 +23449,31 @@ async function refreshIndexesAndSearch(rootDir, pages) {
|
|
|
23198
23449
|
);
|
|
23199
23450
|
}
|
|
23200
23451
|
for (const record of graphOrientation.records) {
|
|
23201
|
-
await writeFileIfChanged(
|
|
23452
|
+
await writeFileIfChanged(path26.join(paths.wikiDir, record.page.path), record.content);
|
|
23202
23453
|
}
|
|
23203
23454
|
for (const record of dashboardRecords) {
|
|
23204
|
-
await writeFileIfChanged(
|
|
23455
|
+
await writeFileIfChanged(path26.join(paths.wikiDir, record.page.path), record.content);
|
|
23205
23456
|
}
|
|
23206
23457
|
if (graphOrientation.report) {
|
|
23207
|
-
await writeJsonFile(
|
|
23458
|
+
await writeJsonFile(path26.join(paths.wikiDir, "graph", "report.json"), graphOrientation.report);
|
|
23208
23459
|
}
|
|
23209
|
-
const existingProjectIndexPaths = (await listFilesRecursive(paths.projectsDir)).filter((absolutePath) => absolutePath.endsWith(".md")).map((absolutePath) => toPosix(
|
|
23460
|
+
const existingProjectIndexPaths = (await listFilesRecursive(paths.projectsDir)).filter((absolutePath) => absolutePath.endsWith(".md")).map((absolutePath) => toPosix(path26.relative(paths.wikiDir, absolutePath)));
|
|
23210
23461
|
const allowedProjectIndexPaths = /* @__PURE__ */ new Set([
|
|
23211
23462
|
"projects/index.md",
|
|
23212
23463
|
...configuredProjects.map((project) => `projects/${project.id}/index.md`)
|
|
23213
23464
|
]);
|
|
23214
23465
|
await Promise.all(
|
|
23215
|
-
existingProjectIndexPaths.filter((relativePath) => !allowedProjectIndexPaths.has(relativePath)).map((relativePath) =>
|
|
23466
|
+
existingProjectIndexPaths.filter((relativePath) => !allowedProjectIndexPaths.has(relativePath)).map((relativePath) => fs22.rm(path26.join(paths.wikiDir, relativePath), { force: true }))
|
|
23216
23467
|
);
|
|
23217
|
-
const existingGraphPages = (await listFilesRecursive(
|
|
23468
|
+
const existingGraphPages = (await listFilesRecursive(path26.join(paths.wikiDir, "graph").replace(/\/$/, "")).catch(() => [])).filter((absolutePath) => absolutePath.endsWith(".md")).map((absolutePath) => toPosix(path26.relative(paths.wikiDir, absolutePath)));
|
|
23218
23469
|
const allowedGraphPages = /* @__PURE__ */ new Set(["graph/index.md", ...graphOrientation.records.map((record) => record.page.path)]);
|
|
23219
23470
|
await Promise.all(
|
|
23220
|
-
existingGraphPages.filter((relativePath) => !allowedGraphPages.has(relativePath)).map((relativePath) =>
|
|
23471
|
+
existingGraphPages.filter((relativePath) => !allowedGraphPages.has(relativePath)).map((relativePath) => fs22.rm(path26.join(paths.wikiDir, relativePath), { force: true }))
|
|
23221
23472
|
);
|
|
23222
|
-
const existingDashboardPages = (await listFilesRecursive(
|
|
23473
|
+
const existingDashboardPages = (await listFilesRecursive(path26.join(paths.wikiDir, "dashboards")).catch(() => [])).filter((absolutePath) => absolutePath.endsWith(".md")).map((absolutePath) => toPosix(path26.relative(paths.wikiDir, absolutePath)));
|
|
23223
23474
|
const allowedDashboardPages = /* @__PURE__ */ new Set(["dashboards/index.md", ...dashboardRecords.map((record) => record.page.path)]);
|
|
23224
23475
|
await Promise.all(
|
|
23225
|
-
existingDashboardPages.filter((relativePath) => !allowedDashboardPages.has(relativePath)).map((relativePath) =>
|
|
23476
|
+
existingDashboardPages.filter((relativePath) => !allowedDashboardPages.has(relativePath)).map((relativePath) => fs22.rm(path26.join(paths.wikiDir, relativePath), { force: true }))
|
|
23226
23477
|
);
|
|
23227
23478
|
await rebuildSearchIndex(paths.searchDbPath, pagesWithGraph, paths.wikiDir);
|
|
23228
23479
|
}
|
|
@@ -23242,7 +23493,7 @@ async function prepareOutputPageSave(rootDir, input) {
|
|
|
23242
23493
|
confidence: 0.74
|
|
23243
23494
|
}
|
|
23244
23495
|
});
|
|
23245
|
-
const absolutePath =
|
|
23496
|
+
const absolutePath = path26.join(paths.wikiDir, output.page.path);
|
|
23246
23497
|
return {
|
|
23247
23498
|
page: output.page,
|
|
23248
23499
|
savedPath: absolutePath,
|
|
@@ -23254,15 +23505,15 @@ async function prepareOutputPageSave(rootDir, input) {
|
|
|
23254
23505
|
async function persistOutputPage(rootDir, input) {
|
|
23255
23506
|
const { paths } = await loadVaultConfig(rootDir);
|
|
23256
23507
|
const prepared = await prepareOutputPageSave(rootDir, input);
|
|
23257
|
-
await ensureDir(
|
|
23258
|
-
await
|
|
23508
|
+
await ensureDir(path26.dirname(prepared.savedPath));
|
|
23509
|
+
await fs22.writeFile(prepared.savedPath, prepared.content, "utf8");
|
|
23259
23510
|
for (const assetFile of prepared.assetFiles) {
|
|
23260
|
-
const assetPath =
|
|
23261
|
-
await ensureDir(
|
|
23511
|
+
const assetPath = path26.join(paths.wikiDir, assetFile.relativePath);
|
|
23512
|
+
await ensureDir(path26.dirname(assetPath));
|
|
23262
23513
|
if (typeof assetFile.content === "string") {
|
|
23263
|
-
await
|
|
23514
|
+
await fs22.writeFile(assetPath, assetFile.content, assetFile.encoding ?? "utf8");
|
|
23264
23515
|
} else {
|
|
23265
|
-
await
|
|
23516
|
+
await fs22.writeFile(assetPath, assetFile.content);
|
|
23266
23517
|
}
|
|
23267
23518
|
}
|
|
23268
23519
|
return { page: prepared.page, savedPath: prepared.savedPath, outputAssets: prepared.outputAssets };
|
|
@@ -23283,7 +23534,7 @@ async function prepareExploreHubSave(rootDir, input) {
|
|
|
23283
23534
|
confidence: 0.76
|
|
23284
23535
|
}
|
|
23285
23536
|
});
|
|
23286
|
-
const absolutePath =
|
|
23537
|
+
const absolutePath = path26.join(paths.wikiDir, hub.page.path);
|
|
23287
23538
|
return {
|
|
23288
23539
|
page: hub.page,
|
|
23289
23540
|
savedPath: absolutePath,
|
|
@@ -23295,15 +23546,15 @@ async function prepareExploreHubSave(rootDir, input) {
|
|
|
23295
23546
|
async function persistExploreHub(rootDir, input) {
|
|
23296
23547
|
const { paths } = await loadVaultConfig(rootDir);
|
|
23297
23548
|
const prepared = await prepareExploreHubSave(rootDir, input);
|
|
23298
|
-
await ensureDir(
|
|
23299
|
-
await
|
|
23549
|
+
await ensureDir(path26.dirname(prepared.savedPath));
|
|
23550
|
+
await fs22.writeFile(prepared.savedPath, prepared.content, "utf8");
|
|
23300
23551
|
for (const assetFile of prepared.assetFiles) {
|
|
23301
|
-
const assetPath =
|
|
23302
|
-
await ensureDir(
|
|
23552
|
+
const assetPath = path26.join(paths.wikiDir, assetFile.relativePath);
|
|
23553
|
+
await ensureDir(path26.dirname(assetPath));
|
|
23303
23554
|
if (typeof assetFile.content === "string") {
|
|
23304
|
-
await
|
|
23555
|
+
await fs22.writeFile(assetPath, assetFile.content, assetFile.encoding ?? "utf8");
|
|
23305
23556
|
} else {
|
|
23306
|
-
await
|
|
23557
|
+
await fs22.writeFile(assetPath, assetFile.content);
|
|
23307
23558
|
}
|
|
23308
23559
|
}
|
|
23309
23560
|
return { page: prepared.page, savedPath: prepared.savedPath, outputAssets: prepared.outputAssets };
|
|
@@ -23321,17 +23572,17 @@ async function stageOutputApprovalBundle(rootDir, stagedPages, options = {}) {
|
|
|
23321
23572
|
]);
|
|
23322
23573
|
const labelsByPath = new Map(stagedPages.filter((item) => item.label).map((item) => [item.page.path, item.label]));
|
|
23323
23574
|
const approvalId = `schedule-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
|
|
23324
|
-
const approvalDir =
|
|
23575
|
+
const approvalDir = path26.join(paths.approvalsDir, approvalId);
|
|
23325
23576
|
await ensureDir(approvalDir);
|
|
23326
|
-
await ensureDir(
|
|
23327
|
-
await ensureDir(
|
|
23577
|
+
await ensureDir(path26.join(approvalDir, "wiki"));
|
|
23578
|
+
await ensureDir(path26.join(approvalDir, "state"));
|
|
23328
23579
|
for (const file of changedFiles) {
|
|
23329
|
-
const targetPath =
|
|
23330
|
-
await ensureDir(
|
|
23580
|
+
const targetPath = path26.join(approvalDir, "wiki", file.relativePath);
|
|
23581
|
+
await ensureDir(path26.dirname(targetPath));
|
|
23331
23582
|
if ("binary" in file && file.binary) {
|
|
23332
|
-
await
|
|
23583
|
+
await fs22.writeFile(targetPath, Buffer.from(file.content, "base64"));
|
|
23333
23584
|
} else {
|
|
23334
|
-
await
|
|
23585
|
+
await fs22.writeFile(targetPath, file.content, "utf8");
|
|
23335
23586
|
}
|
|
23336
23587
|
}
|
|
23337
23588
|
const nextPages = sortGraphPages([
|
|
@@ -23346,7 +23597,7 @@ async function stageOutputApprovalBundle(rootDir, stagedPages, options = {}) {
|
|
|
23346
23597
|
sources: previousGraph?.sources ?? [],
|
|
23347
23598
|
pages: nextPages
|
|
23348
23599
|
};
|
|
23349
|
-
await
|
|
23600
|
+
await fs22.writeFile(path26.join(approvalDir, "state", "graph.json"), JSON.stringify(graph, null, 2), "utf8");
|
|
23350
23601
|
await writeApprovalManifest(paths, {
|
|
23351
23602
|
approvalId,
|
|
23352
23603
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -23396,10 +23647,10 @@ async function executeQuery(rootDir, question, format, options = {}) {
|
|
|
23396
23647
|
const searchResults = searchPages(paths.searchDbPath, question, 5);
|
|
23397
23648
|
const excerpts = await Promise.all(
|
|
23398
23649
|
searchResults.map(async (result) => {
|
|
23399
|
-
const absolutePath =
|
|
23650
|
+
const absolutePath = path26.join(paths.wikiDir, result.path);
|
|
23400
23651
|
try {
|
|
23401
|
-
const content = await
|
|
23402
|
-
const parsed =
|
|
23652
|
+
const content = await fs22.readFile(absolutePath, "utf8");
|
|
23653
|
+
const parsed = matter13(content);
|
|
23403
23654
|
return `# ${result.title}
|
|
23404
23655
|
${truncate(normalizeWhitespace(parsed.content), 1200)}`;
|
|
23405
23656
|
} catch {
|
|
@@ -23672,12 +23923,12 @@ function computeStructuredDiff(current, staged, isBinaryAsset) {
|
|
|
23672
23923
|
let currentBody = current ?? "";
|
|
23673
23924
|
let stagedBody = staged ?? "";
|
|
23674
23925
|
if (current) {
|
|
23675
|
-
const parsed =
|
|
23926
|
+
const parsed = matter13(current);
|
|
23676
23927
|
currentData = parsed.data ?? {};
|
|
23677
23928
|
currentBody = parsed.content;
|
|
23678
23929
|
}
|
|
23679
23930
|
if (staged) {
|
|
23680
|
-
const parsed =
|
|
23931
|
+
const parsed = matter13(staged);
|
|
23681
23932
|
stagedData = parsed.data ?? {};
|
|
23682
23933
|
stagedBody = parsed.content;
|
|
23683
23934
|
}
|
|
@@ -23705,8 +23956,8 @@ function computeChangeSummary(current, staged, changeType) {
|
|
|
23705
23956
|
if (changeType === "delete") return "Removed page";
|
|
23706
23957
|
if (changeType === "promote") return "Promoted from candidate";
|
|
23707
23958
|
if (!current || !staged) return "Updated page";
|
|
23708
|
-
const currentParsed =
|
|
23709
|
-
const stagedParsed =
|
|
23959
|
+
const currentParsed = matter13(current);
|
|
23960
|
+
const stagedParsed = matter13(staged);
|
|
23710
23961
|
const changes = [];
|
|
23711
23962
|
const currentTags = currentParsed.data.tags ?? [];
|
|
23712
23963
|
const stagedTags = stagedParsed.data.tags ?? [];
|
|
@@ -23726,7 +23977,7 @@ function computeChangeSummary(current, staged, changeType) {
|
|
|
23726
23977
|
async function listApprovals(rootDir) {
|
|
23727
23978
|
const { paths } = await loadVaultConfig(rootDir);
|
|
23728
23979
|
const manifests = await Promise.all(
|
|
23729
|
-
(await
|
|
23980
|
+
(await fs22.readdir(paths.approvalsDir, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory()).map(async (entry) => {
|
|
23730
23981
|
try {
|
|
23731
23982
|
return await readApprovalManifest(paths, entry.name);
|
|
23732
23983
|
} catch {
|
|
@@ -23742,8 +23993,8 @@ async function readApproval(rootDir, approvalId, options) {
|
|
|
23742
23993
|
const details = await Promise.all(
|
|
23743
23994
|
manifest.entries.map(async (entry) => {
|
|
23744
23995
|
const currentPath = entry.previousPath ?? entry.nextPath;
|
|
23745
|
-
const currentContent = currentPath ? await
|
|
23746
|
-
const stagedContent = entry.nextPath ? await
|
|
23996
|
+
const currentContent = currentPath ? await fs22.readFile(path26.join(paths.wikiDir, currentPath), "utf8").catch(() => void 0) : void 0;
|
|
23997
|
+
const stagedContent = entry.nextPath ? await fs22.readFile(path26.join(paths.approvalsDir, approvalId, "wiki", entry.nextPath), "utf8").catch(() => void 0) : void 0;
|
|
23747
23998
|
const detail = {
|
|
23748
23999
|
...entry,
|
|
23749
24000
|
currentContent,
|
|
@@ -23785,26 +24036,26 @@ async function acceptApproval(rootDir, approvalId, targets = []) {
|
|
|
23785
24036
|
if (!entry.nextPath) {
|
|
23786
24037
|
throw new Error(`Approval entry ${entry.pageId} is missing a staged path.`);
|
|
23787
24038
|
}
|
|
23788
|
-
const stagedAbsolutePath =
|
|
23789
|
-
const stagedContent = await
|
|
23790
|
-
const targetAbsolutePath =
|
|
23791
|
-
await ensureDir(
|
|
23792
|
-
await
|
|
24039
|
+
const stagedAbsolutePath = path26.join(paths.approvalsDir, approvalId, "wiki", entry.nextPath);
|
|
24040
|
+
const stagedContent = await fs22.readFile(stagedAbsolutePath, "utf8");
|
|
24041
|
+
const targetAbsolutePath = path26.join(paths.wikiDir, entry.nextPath);
|
|
24042
|
+
await ensureDir(path26.dirname(targetAbsolutePath));
|
|
24043
|
+
await fs22.writeFile(targetAbsolutePath, stagedContent, "utf8");
|
|
23793
24044
|
if (entry.changeType === "promote" && entry.previousPath) {
|
|
23794
|
-
await
|
|
24045
|
+
await fs22.rm(path26.join(paths.wikiDir, entry.previousPath), { force: true });
|
|
23795
24046
|
}
|
|
23796
24047
|
const nextPage = bundleGraph?.pages.find((page) => page.id === entry.pageId && page.path === entry.nextPath) ?? parseStoredPage(entry.nextPath, stagedContent);
|
|
23797
24048
|
if (nextPage.kind === "output" && nextPage.outputAssets?.length) {
|
|
23798
|
-
const outputAssetDir =
|
|
23799
|
-
await
|
|
24049
|
+
const outputAssetDir = path26.join(paths.wikiDir, "outputs", "assets", path26.basename(nextPage.path, ".md"));
|
|
24050
|
+
await fs22.rm(outputAssetDir, { recursive: true, force: true });
|
|
23800
24051
|
for (const asset of nextPage.outputAssets) {
|
|
23801
|
-
const stagedAssetPath =
|
|
24052
|
+
const stagedAssetPath = path26.join(paths.approvalsDir, approvalId, "wiki", asset.path);
|
|
23802
24053
|
if (!await fileExists(stagedAssetPath)) {
|
|
23803
24054
|
continue;
|
|
23804
24055
|
}
|
|
23805
|
-
const targetAssetPath =
|
|
23806
|
-
await ensureDir(
|
|
23807
|
-
await
|
|
24056
|
+
const targetAssetPath = path26.join(paths.wikiDir, asset.path);
|
|
24057
|
+
await ensureDir(path26.dirname(targetAssetPath));
|
|
24058
|
+
await fs22.copyFile(stagedAssetPath, targetAssetPath);
|
|
23808
24059
|
}
|
|
23809
24060
|
}
|
|
23810
24061
|
nextPages = nextPages.filter(
|
|
@@ -23815,10 +24066,10 @@ async function acceptApproval(rootDir, approvalId, targets = []) {
|
|
|
23815
24066
|
} else {
|
|
23816
24067
|
const deletedPage = nextPages.find((page) => page.id === entry.pageId || page.path === entry.previousPath) ?? bundleGraph?.pages.find((page) => page.id === entry.pageId || page.path === entry.previousPath) ?? null;
|
|
23817
24068
|
if (entry.previousPath) {
|
|
23818
|
-
await
|
|
24069
|
+
await fs22.rm(path26.join(paths.wikiDir, entry.previousPath), { force: true });
|
|
23819
24070
|
}
|
|
23820
24071
|
if (deletedPage?.kind === "output") {
|
|
23821
|
-
await
|
|
24072
|
+
await fs22.rm(path26.join(paths.wikiDir, "outputs", "assets", path26.basename(deletedPage.path, ".md")), {
|
|
23822
24073
|
recursive: true,
|
|
23823
24074
|
force: true
|
|
23824
24075
|
});
|
|
@@ -23949,10 +24200,10 @@ async function promoteCandidate(rootDir, target) {
|
|
|
23949
24200
|
const { paths } = await loadVaultConfig(rootDir);
|
|
23950
24201
|
const graph = await readJsonFile(paths.graphPath);
|
|
23951
24202
|
const candidate = resolveCandidateTarget(graph?.pages ?? [], target);
|
|
23952
|
-
const raw = await
|
|
23953
|
-
const parsed =
|
|
24203
|
+
const raw = await fs22.readFile(path26.join(paths.wikiDir, candidate.path), "utf8");
|
|
24204
|
+
const parsed = matter13(raw);
|
|
23954
24205
|
const nextUpdatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
23955
|
-
const nextContent =
|
|
24206
|
+
const nextContent = matter13.stringify(parsed.content, {
|
|
23956
24207
|
...parsed.data,
|
|
23957
24208
|
status: "active",
|
|
23958
24209
|
updated_at: nextUpdatedAt,
|
|
@@ -23961,10 +24212,10 @@ async function promoteCandidate(rootDir, target) {
|
|
|
23961
24212
|
)
|
|
23962
24213
|
});
|
|
23963
24214
|
const nextPath = candidateActivePath(candidate);
|
|
23964
|
-
const nextAbsolutePath =
|
|
23965
|
-
await ensureDir(
|
|
23966
|
-
await
|
|
23967
|
-
await
|
|
24215
|
+
const nextAbsolutePath = path26.join(paths.wikiDir, nextPath);
|
|
24216
|
+
await ensureDir(path26.dirname(nextAbsolutePath));
|
|
24217
|
+
await fs22.writeFile(nextAbsolutePath, nextContent, "utf8");
|
|
24218
|
+
await fs22.rm(path26.join(paths.wikiDir, candidate.path), { force: true });
|
|
23968
24219
|
const nextPage = parseStoredPage(nextPath, nextContent, { createdAt: candidate.createdAt, updatedAt: nextUpdatedAt });
|
|
23969
24220
|
const nextPages = sortGraphPages(
|
|
23970
24221
|
(graph?.pages ?? []).filter((page) => page.id !== candidate.id && page.path !== candidate.path).concat(nextPage)
|
|
@@ -24105,10 +24356,10 @@ async function createSupersessionEdge(rootDir, oldPageIdOrPath, newPageIdOrPath)
|
|
|
24105
24356
|
}
|
|
24106
24357
|
const now = /* @__PURE__ */ new Date();
|
|
24107
24358
|
const nextOldPage = markSuperseded(oldPage, newPage.id, now);
|
|
24108
|
-
const oldAbsolutePath =
|
|
24359
|
+
const oldAbsolutePath = path26.join(paths.wikiDir, oldPage.path);
|
|
24109
24360
|
if (await fileExists(oldAbsolutePath)) {
|
|
24110
|
-
const current = await
|
|
24111
|
-
const parsed =
|
|
24361
|
+
const current = await fs22.readFile(oldAbsolutePath, "utf8");
|
|
24362
|
+
const parsed = matter13(current);
|
|
24112
24363
|
const nextData = {
|
|
24113
24364
|
...parsed.data,
|
|
24114
24365
|
freshness: "stale",
|
|
@@ -24116,7 +24367,7 @@ async function createSupersessionEdge(rootDir, oldPageIdOrPath, newPageIdOrPath)
|
|
|
24116
24367
|
superseded_by: newPage.id,
|
|
24117
24368
|
updated_at: nextOldPage.updatedAt
|
|
24118
24369
|
};
|
|
24119
|
-
await
|
|
24370
|
+
await fs22.writeFile(oldAbsolutePath, matter13.stringify(parsed.content, nextData), "utf8");
|
|
24120
24371
|
}
|
|
24121
24372
|
const resolveNodeId = (pageId) => {
|
|
24122
24373
|
const node = graph.nodes.find((item) => item.pageId === pageId);
|
|
@@ -24167,7 +24418,7 @@ async function archiveCandidate(rootDir, target) {
|
|
|
24167
24418
|
const { paths } = await loadVaultConfig(rootDir);
|
|
24168
24419
|
const graph = await readJsonFile(paths.graphPath);
|
|
24169
24420
|
const candidate = resolveCandidateTarget(graph?.pages ?? [], target);
|
|
24170
|
-
await
|
|
24421
|
+
await fs22.rm(path26.join(paths.wikiDir, candidate.path), { force: true });
|
|
24171
24422
|
const nextPages = sortGraphPages((graph?.pages ?? []).filter((page) => page.id !== candidate.id && page.path !== candidate.path));
|
|
24172
24423
|
const nextGraph = {
|
|
24173
24424
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -24206,18 +24457,18 @@ async function archiveCandidate(rootDir, target) {
|
|
|
24206
24457
|
}
|
|
24207
24458
|
async function ensureObsidianWorkspace(rootDir) {
|
|
24208
24459
|
const { config } = await loadVaultConfig(rootDir);
|
|
24209
|
-
const obsidianDir =
|
|
24460
|
+
const obsidianDir = path26.join(rootDir, ".obsidian");
|
|
24210
24461
|
const projectIds = projectEntries(config).map((project) => project.id);
|
|
24211
24462
|
await ensureDir(obsidianDir);
|
|
24212
24463
|
await Promise.all([
|
|
24213
|
-
writeJsonFile(
|
|
24464
|
+
writeJsonFile(path26.join(obsidianDir, "app.json"), {
|
|
24214
24465
|
alwaysUpdateLinks: true,
|
|
24215
24466
|
newFileLocation: "folder",
|
|
24216
24467
|
newFileFolderPath: "wiki/insights",
|
|
24217
24468
|
useMarkdownLinks: false,
|
|
24218
24469
|
attachmentFolderPath: "raw/assets"
|
|
24219
24470
|
}),
|
|
24220
|
-
writeJsonFile(
|
|
24471
|
+
writeJsonFile(path26.join(obsidianDir, "core-plugins.json"), [
|
|
24221
24472
|
"file-explorer",
|
|
24222
24473
|
"global-search",
|
|
24223
24474
|
"switcher",
|
|
@@ -24227,7 +24478,7 @@ async function ensureObsidianWorkspace(rootDir) {
|
|
|
24227
24478
|
"tag-pane",
|
|
24228
24479
|
"page-preview"
|
|
24229
24480
|
]),
|
|
24230
|
-
writeJsonFile(
|
|
24481
|
+
writeJsonFile(path26.join(obsidianDir, "graph.json"), {
|
|
24231
24482
|
"collapse-filter": false,
|
|
24232
24483
|
search: "",
|
|
24233
24484
|
showTags: true,
|
|
@@ -24247,7 +24498,7 @@ async function ensureObsidianWorkspace(rootDir) {
|
|
|
24247
24498
|
],
|
|
24248
24499
|
localJumps: false
|
|
24249
24500
|
}),
|
|
24250
|
-
writeJsonFile(
|
|
24501
|
+
writeJsonFile(path26.join(obsidianDir, "types.json"), {
|
|
24251
24502
|
types: {
|
|
24252
24503
|
page_id: "text",
|
|
24253
24504
|
kind: "text",
|
|
@@ -24268,7 +24519,7 @@ async function ensureObsidianWorkspace(rootDir) {
|
|
|
24268
24519
|
cssclasses: "multitext"
|
|
24269
24520
|
}
|
|
24270
24521
|
}),
|
|
24271
|
-
writeJsonFile(
|
|
24522
|
+
writeJsonFile(path26.join(obsidianDir, "workspace.json"), {
|
|
24272
24523
|
active: "root",
|
|
24273
24524
|
lastOpenFiles: ["wiki/index.md", "wiki/projects/index.md", "wiki/candidates/index.md", "wiki/insights/index.md"],
|
|
24274
24525
|
left: {
|
|
@@ -24281,20 +24532,20 @@ async function ensureObsidianWorkspace(rootDir) {
|
|
|
24281
24532
|
]);
|
|
24282
24533
|
}
|
|
24283
24534
|
async function initLiteVault(rootDir, options) {
|
|
24284
|
-
const rawDir =
|
|
24285
|
-
const wikiDir =
|
|
24286
|
-
const schemaPath =
|
|
24287
|
-
const indexPath =
|
|
24288
|
-
const logPath =
|
|
24535
|
+
const rawDir = path26.join(rootDir, "raw");
|
|
24536
|
+
const wikiDir = path26.join(rootDir, "wiki");
|
|
24537
|
+
const schemaPath = path26.join(rootDir, PRIMARY_SCHEMA_FILENAME);
|
|
24538
|
+
const indexPath = path26.join(wikiDir, "index.md");
|
|
24539
|
+
const logPath = path26.join(wikiDir, "log.md");
|
|
24289
24540
|
await Promise.all([ensureDir(rawDir), ensureDir(wikiDir)]);
|
|
24290
24541
|
if (!await fileExists(schemaPath)) {
|
|
24291
|
-
await
|
|
24542
|
+
await fs22.writeFile(schemaPath, defaultVaultSchema("default"), "utf8");
|
|
24292
24543
|
}
|
|
24293
24544
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
24294
24545
|
if (!await fileExists(indexPath)) {
|
|
24295
|
-
await
|
|
24546
|
+
await fs22.writeFile(
|
|
24296
24547
|
indexPath,
|
|
24297
|
-
|
|
24548
|
+
matter13.stringify(
|
|
24298
24549
|
[
|
|
24299
24550
|
"# Wiki Index",
|
|
24300
24551
|
"",
|
|
@@ -24330,9 +24581,9 @@ async function initLiteVault(rootDir, options) {
|
|
|
24330
24581
|
);
|
|
24331
24582
|
}
|
|
24332
24583
|
if (!await fileExists(logPath)) {
|
|
24333
|
-
await
|
|
24584
|
+
await fs22.writeFile(
|
|
24334
24585
|
logPath,
|
|
24335
|
-
|
|
24586
|
+
matter13.stringify(
|
|
24336
24587
|
[
|
|
24337
24588
|
"# Activity Log",
|
|
24338
24589
|
"",
|
|
@@ -24366,7 +24617,7 @@ async function initLiteVault(rootDir, options) {
|
|
|
24366
24617
|
);
|
|
24367
24618
|
}
|
|
24368
24619
|
if (options.obsidian) {
|
|
24369
|
-
const obsidianDir =
|
|
24620
|
+
const obsidianDir = path26.join(rootDir, ".obsidian");
|
|
24370
24621
|
await ensureDir(obsidianDir);
|
|
24371
24622
|
}
|
|
24372
24623
|
}
|
|
@@ -24380,11 +24631,11 @@ async function initVault(rootDir, options = {}) {
|
|
|
24380
24631
|
const profile = config.profile;
|
|
24381
24632
|
const isResearchProfile = profile.presets.length > 0 || profile.guidedSessionMode === "canonical_review" || profile.dataviewBlocks;
|
|
24382
24633
|
await installConfiguredAgents(rootDir);
|
|
24383
|
-
const insightsIndexPath =
|
|
24634
|
+
const insightsIndexPath = path26.join(paths.wikiDir, "insights", "index.md");
|
|
24384
24635
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
24385
24636
|
await writeFileIfChanged(
|
|
24386
24637
|
insightsIndexPath,
|
|
24387
|
-
|
|
24638
|
+
matter13.stringify(
|
|
24388
24639
|
(isResearchProfile ? [
|
|
24389
24640
|
"# Insights",
|
|
24390
24641
|
"",
|
|
@@ -24430,8 +24681,8 @@ async function initVault(rootDir, options = {}) {
|
|
|
24430
24681
|
)
|
|
24431
24682
|
);
|
|
24432
24683
|
await writeFileIfChanged(
|
|
24433
|
-
|
|
24434
|
-
|
|
24684
|
+
path26.join(paths.wikiDir, "projects", "index.md"),
|
|
24685
|
+
matter13.stringify(["# Projects", "", "- Run `swarmvault compile` to build project rollups.", ""].join("\n"), {
|
|
24435
24686
|
page_id: "projects:index",
|
|
24436
24687
|
kind: "index",
|
|
24437
24688
|
title: "Projects",
|
|
@@ -24453,8 +24704,8 @@ async function initVault(rootDir, options = {}) {
|
|
|
24453
24704
|
})
|
|
24454
24705
|
);
|
|
24455
24706
|
await writeFileIfChanged(
|
|
24456
|
-
|
|
24457
|
-
|
|
24707
|
+
path26.join(paths.wikiDir, "candidates", "index.md"),
|
|
24708
|
+
matter13.stringify(["# Candidates", "", "- Run `swarmvault compile` to stage candidate pages.", ""].join("\n"), {
|
|
24458
24709
|
page_id: "candidates:index",
|
|
24459
24710
|
kind: "index",
|
|
24460
24711
|
title: "Candidates",
|
|
@@ -24480,8 +24731,8 @@ async function initVault(rootDir, options = {}) {
|
|
|
24480
24731
|
}
|
|
24481
24732
|
if (isResearchProfile) {
|
|
24482
24733
|
await writeFileIfChanged(
|
|
24483
|
-
|
|
24484
|
-
|
|
24734
|
+
path26.join(paths.wikiDir, "insights", "research-playbook.md"),
|
|
24735
|
+
matter13.stringify(
|
|
24485
24736
|
[
|
|
24486
24737
|
`# ${requestedProfile === "personal-research" ? "Personal Research Playbook" : "Research Playbook"}`,
|
|
24487
24738
|
"",
|
|
@@ -24639,7 +24890,7 @@ async function compileVault(rootDir, options = {}) {
|
|
|
24639
24890
|
),
|
|
24640
24891
|
Promise.all(
|
|
24641
24892
|
clean.map(async (manifest) => {
|
|
24642
|
-
const cached = await readJsonFile(
|
|
24893
|
+
const cached = await readJsonFile(path26.join(paths.analysesDir, `${manifest.sourceId}.json`));
|
|
24643
24894
|
if (cached) {
|
|
24644
24895
|
analysisProgress.tick(manifest.title);
|
|
24645
24896
|
return cached;
|
|
@@ -24667,22 +24918,22 @@ async function compileVault(rootDir, options = {}) {
|
|
|
24667
24918
|
}
|
|
24668
24919
|
const enriched = enrichResolvedCodeImports(manifest, analysis, codeIndex);
|
|
24669
24920
|
if (analysisSignature(enriched) !== analysisSignature(analysis)) {
|
|
24670
|
-
await writeJsonFile(
|
|
24921
|
+
await writeJsonFile(path26.join(paths.analysesDir, `${analysis.sourceId}.json`), enriched);
|
|
24671
24922
|
}
|
|
24672
24923
|
return enriched;
|
|
24673
24924
|
})
|
|
24674
24925
|
);
|
|
24675
24926
|
await Promise.all([
|
|
24676
|
-
ensureDir(
|
|
24677
|
-
ensureDir(
|
|
24678
|
-
ensureDir(
|
|
24679
|
-
ensureDir(
|
|
24680
|
-
ensureDir(
|
|
24681
|
-
ensureDir(
|
|
24682
|
-
ensureDir(
|
|
24683
|
-
ensureDir(
|
|
24684
|
-
ensureDir(
|
|
24685
|
-
ensureDir(
|
|
24927
|
+
ensureDir(path26.join(paths.wikiDir, "sources")),
|
|
24928
|
+
ensureDir(path26.join(paths.wikiDir, "code")),
|
|
24929
|
+
ensureDir(path26.join(paths.wikiDir, "concepts")),
|
|
24930
|
+
ensureDir(path26.join(paths.wikiDir, "entities")),
|
|
24931
|
+
ensureDir(path26.join(paths.wikiDir, "outputs")),
|
|
24932
|
+
ensureDir(path26.join(paths.wikiDir, "projects")),
|
|
24933
|
+
ensureDir(path26.join(paths.wikiDir, "insights")),
|
|
24934
|
+
ensureDir(path26.join(paths.wikiDir, "candidates")),
|
|
24935
|
+
ensureDir(path26.join(paths.wikiDir, "candidates", "concepts")),
|
|
24936
|
+
ensureDir(path26.join(paths.wikiDir, "candidates", "entities"))
|
|
24686
24937
|
]);
|
|
24687
24938
|
const sync = await syncVaultArtifacts(rootDir, {
|
|
24688
24939
|
schemas,
|
|
@@ -24802,10 +25053,10 @@ async function compileVault(rootDir, options = {}) {
|
|
|
24802
25053
|
}
|
|
24803
25054
|
const estimates = await Promise.all(
|
|
24804
25055
|
sync.allPages.map(async (page) => {
|
|
24805
|
-
const fullPath =
|
|
25056
|
+
const fullPath = path26.join(paths.wikiDir, page.path);
|
|
24806
25057
|
let content = "";
|
|
24807
25058
|
try {
|
|
24808
|
-
content = await
|
|
25059
|
+
content = await fs22.readFile(fullPath, "utf8");
|
|
24809
25060
|
} catch {
|
|
24810
25061
|
}
|
|
24811
25062
|
return estimatePageTokens2(page.id, page.path, page.kind, content, nodeDegreeLookup.get(page.id), page.confidence);
|
|
@@ -24813,9 +25064,9 @@ async function compileVault(rootDir, options = {}) {
|
|
|
24813
25064
|
);
|
|
24814
25065
|
const budgetResult = trimToTokenBudget2(estimates, options.maxTokens);
|
|
24815
25066
|
for (const dropped of budgetResult.dropped) {
|
|
24816
|
-
const fullPath =
|
|
25067
|
+
const fullPath = path26.join(paths.wikiDir, dropped.path);
|
|
24817
25068
|
try {
|
|
24818
|
-
await
|
|
25069
|
+
await fs22.unlink(fullPath);
|
|
24819
25070
|
} catch {
|
|
24820
25071
|
}
|
|
24821
25072
|
}
|
|
@@ -24910,7 +25161,7 @@ async function queryVault(rootDir, options) {
|
|
|
24910
25161
|
assetFiles: staged.assetFiles
|
|
24911
25162
|
}
|
|
24912
25163
|
]);
|
|
24913
|
-
stagedPath =
|
|
25164
|
+
stagedPath = path26.join(approval.approvalDir, "wiki", staged.page.path);
|
|
24914
25165
|
savedPageId = staged.page.id;
|
|
24915
25166
|
approvalId = approval.approvalId;
|
|
24916
25167
|
approvalDir = approval.approvalDir;
|
|
@@ -25169,9 +25420,9 @@ ${orchestrationNotes.join("\n")}
|
|
|
25169
25420
|
approvalId = approval.approvalId;
|
|
25170
25421
|
approvalDir = approval.approvalDir;
|
|
25171
25422
|
stepResults.forEach((result, index) => {
|
|
25172
|
-
result.stagedPath =
|
|
25423
|
+
result.stagedPath = path26.join(approval.approvalDir, "wiki", stagedStepPages[index]?.page.path ?? "");
|
|
25173
25424
|
});
|
|
25174
|
-
stagedHubPath =
|
|
25425
|
+
stagedHubPath = path26.join(approval.approvalDir, "wiki", hubPage.path);
|
|
25175
25426
|
} else {
|
|
25176
25427
|
await refreshVaultAfterOutputSave(rootDir);
|
|
25177
25428
|
}
|
|
@@ -25315,11 +25566,11 @@ async function benchmarkVault(rootDir, options = {}) {
|
|
|
25315
25566
|
}
|
|
25316
25567
|
}
|
|
25317
25568
|
for (const page of graph.pages) {
|
|
25318
|
-
const absolutePath =
|
|
25569
|
+
const absolutePath = path26.join(paths.wikiDir, page.path);
|
|
25319
25570
|
if (!await fileExists(absolutePath)) {
|
|
25320
25571
|
continue;
|
|
25321
25572
|
}
|
|
25322
|
-
const parsed =
|
|
25573
|
+
const parsed = matter13(await fs22.readFile(absolutePath, "utf8"));
|
|
25323
25574
|
pageContentsById.set(page.id, parsed.content);
|
|
25324
25575
|
}
|
|
25325
25576
|
const configuredQuestions = (config.benchmark?.questions ?? []).map((question) => normalizeWhitespace(question)).filter(Boolean);
|
|
@@ -25414,7 +25665,7 @@ async function listGraphHyperedges(rootDir, target, limit = 25) {
|
|
|
25414
25665
|
}
|
|
25415
25666
|
async function readGraphReport(rootDir) {
|
|
25416
25667
|
const { paths } = await loadVaultConfig(rootDir);
|
|
25417
|
-
return readJsonFile(
|
|
25668
|
+
return readJsonFile(path26.join(paths.wikiDir, "graph", "report.json"));
|
|
25418
25669
|
}
|
|
25419
25670
|
async function listGodNodes(rootDir, limit) {
|
|
25420
25671
|
const graph = await ensureCompiledGraph(rootDir);
|
|
@@ -25440,19 +25691,19 @@ async function readPage(rootDir, relativePath) {
|
|
|
25440
25691
|
return null;
|
|
25441
25692
|
}
|
|
25442
25693
|
const { paths } = await loadVaultConfig(rootDir);
|
|
25443
|
-
const absolutePath =
|
|
25694
|
+
const absolutePath = path26.resolve(paths.wikiDir, relativePath);
|
|
25444
25695
|
if (!isPathWithin(paths.wikiDir, absolutePath)) {
|
|
25445
25696
|
return null;
|
|
25446
25697
|
}
|
|
25447
|
-
const stats = await
|
|
25698
|
+
const stats = await fs22.stat(absolutePath).catch(() => null);
|
|
25448
25699
|
if (!stats?.isFile()) {
|
|
25449
25700
|
return null;
|
|
25450
25701
|
}
|
|
25451
|
-
const raw = await
|
|
25452
|
-
const parsed =
|
|
25702
|
+
const raw = await fs22.readFile(absolutePath, "utf8");
|
|
25703
|
+
const parsed = matter13(raw);
|
|
25453
25704
|
return {
|
|
25454
25705
|
path: relativePath,
|
|
25455
|
-
title: typeof parsed.data.title === "string" ? parsed.data.title :
|
|
25706
|
+
title: typeof parsed.data.title === "string" ? parsed.data.title : path26.basename(relativePath, path26.extname(relativePath)),
|
|
25456
25707
|
frontmatter: parsed.data,
|
|
25457
25708
|
content: parsed.content
|
|
25458
25709
|
};
|
|
@@ -25519,7 +25770,7 @@ function tierLintFindings(paths, graph, consolidationConfig, now = /* @__PURE__
|
|
|
25519
25770
|
severity: "info",
|
|
25520
25771
|
code: "stale_working_tier",
|
|
25521
25772
|
message: `Working-tier insight ${page.title} has not been consolidated after the session window.`,
|
|
25522
|
-
pagePath:
|
|
25773
|
+
pagePath: path26.join(paths.wikiDir, page.path),
|
|
25523
25774
|
relatedPageIds: [page.id]
|
|
25524
25775
|
});
|
|
25525
25776
|
}
|
|
@@ -25531,7 +25782,7 @@ function tierLintFindings(paths, graph, consolidationConfig, now = /* @__PURE__
|
|
|
25531
25782
|
severity: "warning",
|
|
25532
25783
|
code: "broken_consolidation_basis",
|
|
25533
25784
|
message: `Tier page ${page.title} references missing lower-tier page ids: ${missing.join(", ")}.`,
|
|
25534
|
-
pagePath:
|
|
25785
|
+
pagePath: path26.join(paths.wikiDir, page.path),
|
|
25535
25786
|
relatedPageIds: [page.id]
|
|
25536
25787
|
});
|
|
25537
25788
|
}
|
|
@@ -25541,7 +25792,7 @@ function tierLintFindings(paths, graph, consolidationConfig, now = /* @__PURE__
|
|
|
25541
25792
|
severity: "warning",
|
|
25542
25793
|
code: "semantic_without_episodic_basis",
|
|
25543
25794
|
message: `Semantic-tier page ${page.title} has no episodic basis recorded.`,
|
|
25544
|
-
pagePath:
|
|
25795
|
+
pagePath: path26.join(paths.wikiDir, page.path),
|
|
25545
25796
|
relatedPageIds: [page.id]
|
|
25546
25797
|
});
|
|
25547
25798
|
}
|
|
@@ -25562,7 +25813,7 @@ function decayLintFindings(paths, graph, freshnessConfig, now = /* @__PURE__ */
|
|
|
25562
25813
|
severity: "info",
|
|
25563
25814
|
code: "decayed-pages",
|
|
25564
25815
|
message: `Page ${page.title} has decayed (score=${score.toFixed(2)}, below threshold ${staleThreshold}).`,
|
|
25565
|
-
pagePath:
|
|
25816
|
+
pagePath: path26.join(paths.wikiDir, page.path),
|
|
25566
25817
|
relatedPageIds: [page.id]
|
|
25567
25818
|
});
|
|
25568
25819
|
}
|
|
@@ -25571,7 +25822,7 @@ function decayLintFindings(paths, graph, freshnessConfig, now = /* @__PURE__ */
|
|
|
25571
25822
|
severity: "warning",
|
|
25572
25823
|
code: "broken_supersession",
|
|
25573
25824
|
message: `Page ${page.title} is marked supersededBy ${supersededBy}, but that page does not exist.`,
|
|
25574
|
-
pagePath:
|
|
25825
|
+
pagePath: path26.join(paths.wikiDir, page.path),
|
|
25575
25826
|
relatedPageIds: [page.id]
|
|
25576
25827
|
});
|
|
25577
25828
|
}
|
|
@@ -25580,7 +25831,7 @@ function decayLintFindings(paths, graph, freshnessConfig, now = /* @__PURE__ */
|
|
|
25580
25831
|
severity: "info",
|
|
25581
25832
|
code: "inconsistent_decay",
|
|
25582
25833
|
message: `Page ${page.title} is marked stale but decay score ${score.toFixed(2)} is above the threshold.`,
|
|
25583
|
-
pagePath:
|
|
25834
|
+
pagePath: path26.join(paths.wikiDir, page.path),
|
|
25584
25835
|
relatedPageIds: [page.id]
|
|
25585
25836
|
});
|
|
25586
25837
|
}
|
|
@@ -25602,7 +25853,7 @@ function structuralLintFindings(_rootDir, paths, graph, schemas, manifests, sour
|
|
|
25602
25853
|
severity: "warning",
|
|
25603
25854
|
code: "stale_page",
|
|
25604
25855
|
message: `Page ${page.title} is stale because the vault schema changed.`,
|
|
25605
|
-
pagePath:
|
|
25856
|
+
pagePath: path26.join(paths.wikiDir, page.path),
|
|
25606
25857
|
relatedPageIds: [page.id]
|
|
25607
25858
|
});
|
|
25608
25859
|
}
|
|
@@ -25615,7 +25866,7 @@ function structuralLintFindings(_rootDir, paths, graph, schemas, manifests, sour
|
|
|
25615
25866
|
severity: "warning",
|
|
25616
25867
|
code: "stale_page",
|
|
25617
25868
|
message: `Page ${page.title} is stale because source ${sourceId} changed.`,
|
|
25618
|
-
pagePath:
|
|
25869
|
+
pagePath: path26.join(paths.wikiDir, page.path),
|
|
25619
25870
|
relatedSourceIds: [sourceId],
|
|
25620
25871
|
relatedPageIds: [page.id]
|
|
25621
25872
|
});
|
|
@@ -25626,13 +25877,13 @@ function structuralLintFindings(_rootDir, paths, graph, schemas, manifests, sour
|
|
|
25626
25877
|
severity: "info",
|
|
25627
25878
|
code: "orphan_page",
|
|
25628
25879
|
message: `Page ${page.title} has no backlinks.`,
|
|
25629
|
-
pagePath:
|
|
25880
|
+
pagePath: path26.join(paths.wikiDir, page.path),
|
|
25630
25881
|
relatedPageIds: [page.id]
|
|
25631
25882
|
});
|
|
25632
25883
|
}
|
|
25633
|
-
const absolutePath =
|
|
25884
|
+
const absolutePath = path26.join(paths.wikiDir, page.path);
|
|
25634
25885
|
if (await fileExists(absolutePath)) {
|
|
25635
|
-
const content = await
|
|
25886
|
+
const content = await fs22.readFile(absolutePath, "utf8");
|
|
25636
25887
|
const claimLines = extractClaimSectionLines(content);
|
|
25637
25888
|
if (claimLines !== null) {
|
|
25638
25889
|
const uncited = claimLines.filter(
|
|
@@ -25789,8 +26040,8 @@ async function consolidateVault(rootDir, options = {}) {
|
|
|
25789
26040
|
}
|
|
25790
26041
|
|
|
25791
26042
|
// src/watch.ts
|
|
25792
|
-
import
|
|
25793
|
-
import
|
|
26043
|
+
import fs23 from "fs/promises";
|
|
26044
|
+
import path27 from "path";
|
|
25794
26045
|
import process3 from "process";
|
|
25795
26046
|
import chokidar from "chokidar";
|
|
25796
26047
|
var MAX_BACKOFF_MS = 3e4;
|
|
@@ -25844,7 +26095,7 @@ function isCodeOnlyChange(reasons) {
|
|
|
25844
26095
|
for (const reason of reasons) {
|
|
25845
26096
|
const match = reason.match(FILE_CHANGE_RE);
|
|
25846
26097
|
if (!match) return false;
|
|
25847
|
-
const ext =
|
|
26098
|
+
const ext = path27.extname(match[1]).toLowerCase();
|
|
25848
26099
|
if (!ext || !CODE_EXTENSIONS.has(ext)) return false;
|
|
25849
26100
|
}
|
|
25850
26101
|
return reasons.size > 0;
|
|
@@ -25853,7 +26104,7 @@ function hasNonCodeChanges(reasons) {
|
|
|
25853
26104
|
for (const reason of reasons) {
|
|
25854
26105
|
const match = reason.match(FILE_CHANGE_RE);
|
|
25855
26106
|
if (!match) return true;
|
|
25856
|
-
const ext =
|
|
26107
|
+
const ext = path27.extname(match[1]).toLowerCase();
|
|
25857
26108
|
if (!ext || !CODE_EXTENSIONS.has(ext)) return true;
|
|
25858
26109
|
}
|
|
25859
26110
|
return false;
|
|
@@ -25866,17 +26117,17 @@ function collectNonCodePaths(reasons) {
|
|
|
25866
26117
|
result.push(reason);
|
|
25867
26118
|
continue;
|
|
25868
26119
|
}
|
|
25869
|
-
const ext =
|
|
26120
|
+
const ext = path27.extname(match[1]).toLowerCase();
|
|
25870
26121
|
if (!ext || !CODE_EXTENSIONS.has(ext)) result.push(match[1]);
|
|
25871
26122
|
}
|
|
25872
26123
|
return result;
|
|
25873
26124
|
}
|
|
25874
26125
|
function hasIgnoredRepoSegment(baseDir, targetPath) {
|
|
25875
|
-
const relativePath =
|
|
26126
|
+
const relativePath = path27.relative(baseDir, targetPath);
|
|
25876
26127
|
if (!relativePath || relativePath.startsWith("..")) {
|
|
25877
26128
|
return false;
|
|
25878
26129
|
}
|
|
25879
|
-
return relativePath.split(
|
|
26130
|
+
return relativePath.split(path27.sep).some((segment) => REPO_WATCH_IGNORES.has(segment));
|
|
25880
26131
|
}
|
|
25881
26132
|
function workspaceIgnoreRoots(rootDir, paths) {
|
|
25882
26133
|
return [
|
|
@@ -25885,22 +26136,22 @@ function workspaceIgnoreRoots(rootDir, paths) {
|
|
|
25885
26136
|
paths.stateDir,
|
|
25886
26137
|
paths.agentDir,
|
|
25887
26138
|
paths.inboxDir,
|
|
25888
|
-
|
|
25889
|
-
|
|
25890
|
-
|
|
25891
|
-
].map((candidate) =>
|
|
26139
|
+
path27.join(rootDir, ".claude"),
|
|
26140
|
+
path27.join(rootDir, ".cursor"),
|
|
26141
|
+
path27.join(rootDir, ".obsidian")
|
|
26142
|
+
].map((candidate) => path27.resolve(candidate));
|
|
25892
26143
|
}
|
|
25893
26144
|
async function resolveWatchTargets(rootDir, paths, options) {
|
|
25894
|
-
const targets = /* @__PURE__ */ new Set([
|
|
26145
|
+
const targets = /* @__PURE__ */ new Set([path27.resolve(paths.inboxDir)]);
|
|
25895
26146
|
if (options.repo) {
|
|
25896
26147
|
for (const repoRoot of await resolveWatchedRepoRoots(rootDir, { overrideRoots: options.overrideRoots })) {
|
|
25897
|
-
targets.add(
|
|
26148
|
+
targets.add(path27.resolve(repoRoot));
|
|
25898
26149
|
}
|
|
25899
26150
|
}
|
|
25900
26151
|
return [...targets].sort((left, right) => left.localeCompare(right));
|
|
25901
26152
|
}
|
|
25902
26153
|
function resolveRootRelative(rootDir, candidate) {
|
|
25903
|
-
return
|
|
26154
|
+
return path27.isAbsolute(candidate) ? path27.resolve(candidate) : path27.resolve(rootDir, candidate);
|
|
25904
26155
|
}
|
|
25905
26156
|
async function resolveWatchedRepoRoots(rootDir, options = {}) {
|
|
25906
26157
|
const override = options.overrideRoots?.filter(Boolean) ?? [];
|
|
@@ -25914,17 +26165,17 @@ async function resolveWatchedRepoRoots(rootDir, options = {}) {
|
|
|
25914
26165
|
const excluded = new Set(
|
|
25915
26166
|
(watchConfig.excludeRepoRoots ?? []).filter(Boolean).map((candidate) => resolveRootRelative(rootDir, candidate))
|
|
25916
26167
|
);
|
|
25917
|
-
return dedupeSorted(baseRoots.filter((candidate) => !excluded.has(
|
|
26168
|
+
return dedupeSorted(baseRoots.filter((candidate) => !excluded.has(path27.resolve(candidate))));
|
|
25918
26169
|
}
|
|
25919
26170
|
async function listWatchedRoots(rootDir, options = {}) {
|
|
25920
26171
|
return resolveWatchedRepoRoots(rootDir, options);
|
|
25921
26172
|
}
|
|
25922
26173
|
function dedupeSorted(values) {
|
|
25923
|
-
return [...new Set(values.map((value) =>
|
|
26174
|
+
return [...new Set(values.map((value) => path27.resolve(value)))].sort((left, right) => left.localeCompare(right));
|
|
25924
26175
|
}
|
|
25925
26176
|
async function readConfigJson(rootDir) {
|
|
25926
|
-
const configPath =
|
|
25927
|
-
const raw = await
|
|
26177
|
+
const configPath = path27.join(rootDir, "swarmvault.config.json");
|
|
26178
|
+
const raw = await fs23.readFile(configPath, "utf8");
|
|
25928
26179
|
const parsed = JSON.parse(raw);
|
|
25929
26180
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
25930
26181
|
throw new Error("swarmvault.config.json must contain a JSON object.");
|
|
@@ -25932,7 +26183,7 @@ async function readConfigJson(rootDir) {
|
|
|
25932
26183
|
return { path: configPath, content: parsed };
|
|
25933
26184
|
}
|
|
25934
26185
|
async function writeConfigJson(configPath, content) {
|
|
25935
|
-
await
|
|
26186
|
+
await fs23.writeFile(configPath, `${JSON.stringify(content, null, 2)}
|
|
25936
26187
|
`, "utf8");
|
|
25937
26188
|
}
|
|
25938
26189
|
function getWatchBlock(config) {
|
|
@@ -26105,7 +26356,7 @@ async function watchVault(rootDir, options = {}) {
|
|
|
26105
26356
|
const { paths } = await initWorkspace(rootDir);
|
|
26106
26357
|
const baseDebounceMs = options.debounceMs ?? 900;
|
|
26107
26358
|
const ignoredRoots = workspaceIgnoreRoots(rootDir, paths);
|
|
26108
|
-
const inboxWatchRoot =
|
|
26359
|
+
const inboxWatchRoot = path27.resolve(paths.inboxDir);
|
|
26109
26360
|
let watchTargets = await resolveWatchTargets(rootDir, paths, options);
|
|
26110
26361
|
let timer;
|
|
26111
26362
|
let running = false;
|
|
@@ -26120,7 +26371,7 @@ async function watchVault(rootDir, options = {}) {
|
|
|
26120
26371
|
usePolling: true,
|
|
26121
26372
|
interval: 100,
|
|
26122
26373
|
ignored: (targetPath) => {
|
|
26123
|
-
const absolutePath =
|
|
26374
|
+
const absolutePath = path27.resolve(targetPath);
|
|
26124
26375
|
const primaryTarget = watchTargets.filter((watchTarget) => isPathWithin(watchTarget, absolutePath)).sort((left, right) => right.length - left.length)[0] ?? null;
|
|
26125
26376
|
if (!primaryTarget) {
|
|
26126
26377
|
return false;
|
|
@@ -26322,8 +26573,8 @@ async function watchVault(rootDir, options = {}) {
|
|
|
26322
26573
|
}
|
|
26323
26574
|
};
|
|
26324
26575
|
const reasonForPath = (targetPath) => {
|
|
26325
|
-
const baseDir = watchTargets.filter((watchTarget) => isPathWithin(watchTarget,
|
|
26326
|
-
return
|
|
26576
|
+
const baseDir = watchTargets.filter((watchTarget) => isPathWithin(watchTarget, path27.resolve(targetPath))).sort((left, right) => right.length - left.length)[0] ?? paths.inboxDir;
|
|
26577
|
+
return path27.relative(baseDir, targetPath) || ".";
|
|
26327
26578
|
};
|
|
26328
26579
|
watcher.on("add", (filePath) => schedule(`add:${reasonForPath(filePath)}`)).on("change", (filePath) => schedule(`change:${reasonForPath(filePath)}`)).on("unlink", (filePath) => schedule(`unlink:${reasonForPath(filePath)}`)).on("addDir", (dirPath) => schedule(`addDir:${reasonForPath(dirPath)}`)).on("unlinkDir", (dirPath) => schedule(`unlinkDir:${reasonForPath(dirPath)}`)).on("error", (caught) => schedule(`error:${caught instanceof Error ? caught.message : String(caught)}`));
|
|
26329
26580
|
await new Promise((resolve, reject) => {
|
|
@@ -26362,7 +26613,7 @@ async function getWatchStatus(rootDir) {
|
|
|
26362
26613
|
}
|
|
26363
26614
|
|
|
26364
26615
|
// src/mcp.ts
|
|
26365
|
-
var SERVER_VERSION = "0.
|
|
26616
|
+
var SERVER_VERSION = "1.0.0";
|
|
26366
26617
|
async function createMcpServer(rootDir) {
|
|
26367
26618
|
const server = new McpServer({
|
|
26368
26619
|
name: "swarmvault",
|
|
@@ -26694,6 +26945,19 @@ async function createMcpServer(rootDir) {
|
|
|
26694
26945
|
return asToolText(result);
|
|
26695
26946
|
})
|
|
26696
26947
|
);
|
|
26948
|
+
server.registerTool(
|
|
26949
|
+
"migrate",
|
|
26950
|
+
{
|
|
26951
|
+
description: "Detect the vault's version and preview the migration plan to the current SwarmVault version.",
|
|
26952
|
+
inputSchema: {
|
|
26953
|
+
target: z8.string().optional().describe("Optional target version cap (migrations with toVersion above this are skipped)")
|
|
26954
|
+
}
|
|
26955
|
+
},
|
|
26956
|
+
safeHandler(async ({ target }) => {
|
|
26957
|
+
const plan = await runMigration(rootDir, { targetVersion: target, dryRun: true });
|
|
26958
|
+
return asToolText(plan);
|
|
26959
|
+
})
|
|
26960
|
+
);
|
|
26697
26961
|
server.registerResource(
|
|
26698
26962
|
"swarmvault-config",
|
|
26699
26963
|
"swarmvault://config",
|
|
@@ -26760,7 +27024,7 @@ async function createMcpServer(rootDir) {
|
|
|
26760
27024
|
},
|
|
26761
27025
|
async () => {
|
|
26762
27026
|
const { paths } = await loadVaultConfig(rootDir);
|
|
26763
|
-
const files = (await listFilesRecursive(paths.sessionsDir)).filter((filePath) => filePath.endsWith(".md")).map((filePath) => toPosix(
|
|
27027
|
+
const files = (await listFilesRecursive(paths.sessionsDir)).filter((filePath) => filePath.endsWith(".md")).map((filePath) => toPosix(path28.relative(paths.sessionsDir, filePath))).sort();
|
|
26764
27028
|
return asTextResource("swarmvault://sessions", JSON.stringify(files, null, 2));
|
|
26765
27029
|
}
|
|
26766
27030
|
);
|
|
@@ -26793,8 +27057,8 @@ async function createMcpServer(rootDir) {
|
|
|
26793
27057
|
return asTextResource(`swarmvault://pages/${encodedPath}`, `Page not found: ${relativePath}`);
|
|
26794
27058
|
}
|
|
26795
27059
|
const { paths } = await loadVaultConfig(rootDir);
|
|
26796
|
-
const absolutePath =
|
|
26797
|
-
return asTextResource(`swarmvault://pages/${encodedPath}`, await
|
|
27060
|
+
const absolutePath = path28.resolve(paths.wikiDir, relativePath);
|
|
27061
|
+
return asTextResource(`swarmvault://pages/${encodedPath}`, await fs24.readFile(absolutePath, "utf8"));
|
|
26798
27062
|
}
|
|
26799
27063
|
);
|
|
26800
27064
|
server.registerResource(
|
|
@@ -26802,11 +27066,11 @@ async function createMcpServer(rootDir) {
|
|
|
26802
27066
|
new ResourceTemplate("swarmvault://sessions/{path}", {
|
|
26803
27067
|
list: async () => {
|
|
26804
27068
|
const { paths } = await loadVaultConfig(rootDir);
|
|
26805
|
-
const files = (await listFilesRecursive(paths.sessionsDir)).filter((filePath) => filePath.endsWith(".md")).map((filePath) => toPosix(
|
|
27069
|
+
const files = (await listFilesRecursive(paths.sessionsDir)).filter((filePath) => filePath.endsWith(".md")).map((filePath) => toPosix(path28.relative(paths.sessionsDir, filePath))).sort();
|
|
26806
27070
|
return {
|
|
26807
27071
|
resources: files.map((relativePath) => ({
|
|
26808
27072
|
uri: `swarmvault://sessions/${encodeURIComponent(relativePath)}`,
|
|
26809
|
-
name:
|
|
27073
|
+
name: path28.basename(relativePath, ".md"),
|
|
26810
27074
|
title: relativePath,
|
|
26811
27075
|
description: "SwarmVault session artifact",
|
|
26812
27076
|
mimeType: "text/markdown"
|
|
@@ -26823,11 +27087,11 @@ async function createMcpServer(rootDir) {
|
|
|
26823
27087
|
const { paths } = await loadVaultConfig(rootDir);
|
|
26824
27088
|
const encodedPath = typeof variables.path === "string" ? variables.path : "";
|
|
26825
27089
|
const relativePath = decodeURIComponent(encodedPath);
|
|
26826
|
-
const absolutePath =
|
|
27090
|
+
const absolutePath = path28.resolve(paths.sessionsDir, relativePath);
|
|
26827
27091
|
if (!isPathWithin(paths.sessionsDir, absolutePath) || !await fileExists(absolutePath)) {
|
|
26828
27092
|
return asTextResource(`swarmvault://sessions/${encodedPath}`, `Session not found: ${relativePath}`);
|
|
26829
27093
|
}
|
|
26830
|
-
return asTextResource(`swarmvault://sessions/${encodedPath}`, await
|
|
27094
|
+
return asTextResource(`swarmvault://sessions/${encodedPath}`, await fs24.readFile(absolutePath, "utf8"));
|
|
26831
27095
|
}
|
|
26832
27096
|
);
|
|
26833
27097
|
return server;
|
|
@@ -26885,14 +27149,76 @@ function asTextResource(uri, text) {
|
|
|
26885
27149
|
};
|
|
26886
27150
|
}
|
|
26887
27151
|
|
|
27152
|
+
// src/providers/openai-compatible-capabilities.ts
|
|
27153
|
+
var OPENAI_COMPATIBLE_CAPABILITY_MATRIX = Object.freeze({
|
|
27154
|
+
openai: {
|
|
27155
|
+
presetId: "openai",
|
|
27156
|
+
apiStyle: "responses",
|
|
27157
|
+
capabilities: ["responses", "chat", "structured", "tools", "vision", "embeddings", "streaming", "image_generation", "audio"],
|
|
27158
|
+
notes: "Reference implementation. Supports responses API, strict structured output, tool calling, vision, image generation, and Whisper transcription."
|
|
27159
|
+
},
|
|
27160
|
+
"openai-compatible": {
|
|
27161
|
+
presetId: "openai-compatible",
|
|
27162
|
+
apiStyle: "responses",
|
|
27163
|
+
capabilities: ["chat", "structured", "embeddings", "audio"],
|
|
27164
|
+
notes: "Generic fallback for self-hosted backends. Structured output adherence varies; verify capability flags per deployment."
|
|
27165
|
+
},
|
|
27166
|
+
openrouter: {
|
|
27167
|
+
presetId: "openrouter",
|
|
27168
|
+
apiStyle: "chat",
|
|
27169
|
+
capabilities: ["chat", "structured", "embeddings"],
|
|
27170
|
+
notes: "Router of upstream models. No responses API, no vision at the gateway level, structured output requires model-specific care."
|
|
27171
|
+
},
|
|
27172
|
+
groq: {
|
|
27173
|
+
presetId: "groq",
|
|
27174
|
+
apiStyle: "chat",
|
|
27175
|
+
capabilities: ["chat", "structured", "embeddings", "audio"],
|
|
27176
|
+
notes: "Fast chat completions, Whisper-compatible audio endpoint, no vision, no responses API."
|
|
27177
|
+
},
|
|
27178
|
+
together: {
|
|
27179
|
+
presetId: "together",
|
|
27180
|
+
apiStyle: "chat",
|
|
27181
|
+
capabilities: ["chat", "structured", "embeddings"],
|
|
27182
|
+
notes: "Chat completions with mixed structured-output reliability across hosted models. No vision or audio."
|
|
27183
|
+
},
|
|
27184
|
+
xai: {
|
|
27185
|
+
presetId: "xai",
|
|
27186
|
+
apiStyle: "chat",
|
|
27187
|
+
capabilities: ["chat", "structured", "embeddings"],
|
|
27188
|
+
notes: "Grok API. Chat and structured output; no vision or audio in the open surface."
|
|
27189
|
+
},
|
|
27190
|
+
cerebras: {
|
|
27191
|
+
presetId: "cerebras",
|
|
27192
|
+
apiStyle: "chat",
|
|
27193
|
+
capabilities: ["chat", "structured", "embeddings"],
|
|
27194
|
+
notes: "High-throughput inference. No vision, no audio, no image generation."
|
|
27195
|
+
},
|
|
27196
|
+
ollama: {
|
|
27197
|
+
presetId: "ollama",
|
|
27198
|
+
apiStyle: "chat",
|
|
27199
|
+
capabilities: ["chat", "structured", "tools", "vision", "embeddings", "streaming", "local", "audio"],
|
|
27200
|
+
notes: "Local-first. Capabilities depend on which models are installed; structured output is best-effort."
|
|
27201
|
+
}
|
|
27202
|
+
});
|
|
27203
|
+
function lookupPresetCapabilities(presetId) {
|
|
27204
|
+
return OPENAI_COMPATIBLE_CAPABILITY_MATRIX[presetId] ?? null;
|
|
27205
|
+
}
|
|
27206
|
+
async function withCapabilityFallback(provider, capability, run, fallback) {
|
|
27207
|
+
if (provider.capabilities.has(capability)) {
|
|
27208
|
+
return { supported: true, reason: null, value: await run() };
|
|
27209
|
+
}
|
|
27210
|
+
const fallbackValue = await fallback();
|
|
27211
|
+
return { supported: false, reason: "unsupported", value: fallbackValue };
|
|
27212
|
+
}
|
|
27213
|
+
|
|
26888
27214
|
// src/schedule.ts
|
|
26889
|
-
import
|
|
26890
|
-
import
|
|
27215
|
+
import fs25 from "fs/promises";
|
|
27216
|
+
import path29 from "path";
|
|
26891
27217
|
function scheduleStatePath(schedulesDir, jobId) {
|
|
26892
|
-
return
|
|
27218
|
+
return path29.join(schedulesDir, `${encodeURIComponent(jobId)}.json`);
|
|
26893
27219
|
}
|
|
26894
27220
|
function scheduleLockPath(schedulesDir, jobId) {
|
|
26895
|
-
return
|
|
27221
|
+
return path29.join(schedulesDir, `${encodeURIComponent(jobId)}.lock`);
|
|
26896
27222
|
}
|
|
26897
27223
|
function parseEveryDuration(value) {
|
|
26898
27224
|
const match = value.trim().match(/^(\d+)(m|h|d)$/i);
|
|
@@ -26995,13 +27321,13 @@ async function acquireJobLease(rootDir, jobId) {
|
|
|
26995
27321
|
const { paths } = await loadVaultConfig(rootDir);
|
|
26996
27322
|
const leasePath = scheduleLockPath(paths.schedulesDir, jobId);
|
|
26997
27323
|
await ensureDir(paths.schedulesDir);
|
|
26998
|
-
const handle = await
|
|
27324
|
+
const handle = await fs25.open(leasePath, "wx");
|
|
26999
27325
|
await handle.writeFile(`${process.pid}
|
|
27000
27326
|
${(/* @__PURE__ */ new Date()).toISOString()}
|
|
27001
27327
|
`);
|
|
27002
27328
|
await handle.close();
|
|
27003
27329
|
return async () => {
|
|
27004
|
-
await
|
|
27330
|
+
await fs25.rm(leasePath, { force: true });
|
|
27005
27331
|
};
|
|
27006
27332
|
}
|
|
27007
27333
|
async function listSchedules(rootDir) {
|
|
@@ -27160,9 +27486,9 @@ async function serveSchedules(rootDir, pollMs = 3e4) {
|
|
|
27160
27486
|
|
|
27161
27487
|
// src/sources.ts
|
|
27162
27488
|
import { spawn as spawn2 } from "child_process";
|
|
27163
|
-
import
|
|
27164
|
-
import
|
|
27165
|
-
import
|
|
27489
|
+
import fs26 from "fs/promises";
|
|
27490
|
+
import path30 from "path";
|
|
27491
|
+
import matter14 from "gray-matter";
|
|
27166
27492
|
import { JSDOM as JSDOM3 } from "jsdom";
|
|
27167
27493
|
var DEFAULT_CRAWL_MAX_PAGES = 12;
|
|
27168
27494
|
var DEFAULT_CRAWL_MAX_DEPTH = 2;
|
|
@@ -27207,24 +27533,24 @@ function emptyManagedSourceSyncCounts() {
|
|
|
27207
27533
|
};
|
|
27208
27534
|
}
|
|
27209
27535
|
function withinRoot2(rootPath, targetPath) {
|
|
27210
|
-
const relative =
|
|
27211
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
27536
|
+
const relative = path30.relative(rootPath, targetPath);
|
|
27537
|
+
return relative === "" || !relative.startsWith("..") && !path30.isAbsolute(relative);
|
|
27212
27538
|
}
|
|
27213
27539
|
async function findNearestGitRoot3(startPath) {
|
|
27214
|
-
let current =
|
|
27540
|
+
let current = path30.resolve(startPath);
|
|
27215
27541
|
try {
|
|
27216
|
-
const stat = await
|
|
27542
|
+
const stat = await fs26.stat(current);
|
|
27217
27543
|
if (!stat.isDirectory()) {
|
|
27218
|
-
current =
|
|
27544
|
+
current = path30.dirname(current);
|
|
27219
27545
|
}
|
|
27220
27546
|
} catch {
|
|
27221
|
-
current =
|
|
27547
|
+
current = path30.dirname(current);
|
|
27222
27548
|
}
|
|
27223
27549
|
while (true) {
|
|
27224
|
-
if (await fileExists(
|
|
27550
|
+
if (await fileExists(path30.join(current, ".git"))) {
|
|
27225
27551
|
return current;
|
|
27226
27552
|
}
|
|
27227
|
-
const parent =
|
|
27553
|
+
const parent = path30.dirname(current);
|
|
27228
27554
|
if (parent === current) {
|
|
27229
27555
|
return null;
|
|
27230
27556
|
}
|
|
@@ -27298,7 +27624,7 @@ function isAllowedDocsCandidate(candidate, startUrl) {
|
|
|
27298
27624
|
if (candidate.origin !== startUrl.origin) {
|
|
27299
27625
|
return false;
|
|
27300
27626
|
}
|
|
27301
|
-
const extension =
|
|
27627
|
+
const extension = path30.extname(candidate.pathname).toLowerCase();
|
|
27302
27628
|
if (extension && extension !== ".html" && extension !== ".htm" && extension !== ".md") {
|
|
27303
27629
|
return false;
|
|
27304
27630
|
}
|
|
@@ -27387,14 +27713,14 @@ function matchesManagedSourceSpec(existing, input) {
|
|
|
27387
27713
|
return false;
|
|
27388
27714
|
}
|
|
27389
27715
|
if (input.kind === "directory" || input.kind === "file") {
|
|
27390
|
-
return
|
|
27716
|
+
return path30.resolve(existing.path ?? "") === path30.resolve(input.path);
|
|
27391
27717
|
}
|
|
27392
27718
|
return (existing.url ?? "") === input.url;
|
|
27393
27719
|
}
|
|
27394
27720
|
async function resolveManagedSourceInput(rootDir, input) {
|
|
27395
|
-
const absoluteInput =
|
|
27721
|
+
const absoluteInput = path30.resolve(rootDir, input);
|
|
27396
27722
|
if (!(input.startsWith("http://") || input.startsWith("https://"))) {
|
|
27397
|
-
const stat = await
|
|
27723
|
+
const stat = await fs26.stat(absoluteInput).catch(() => null);
|
|
27398
27724
|
if (!stat) {
|
|
27399
27725
|
throw new Error(`Source not found: ${input}`);
|
|
27400
27726
|
}
|
|
@@ -27402,7 +27728,7 @@ async function resolveManagedSourceInput(rootDir, input) {
|
|
|
27402
27728
|
return {
|
|
27403
27729
|
kind: "file",
|
|
27404
27730
|
path: absoluteInput,
|
|
27405
|
-
title:
|
|
27731
|
+
title: path30.basename(absoluteInput, path30.extname(absoluteInput)) || absoluteInput
|
|
27406
27732
|
};
|
|
27407
27733
|
}
|
|
27408
27734
|
if (!stat.isDirectory()) {
|
|
@@ -27414,7 +27740,7 @@ async function resolveManagedSourceInput(rootDir, input) {
|
|
|
27414
27740
|
kind: "directory",
|
|
27415
27741
|
path: absoluteInput,
|
|
27416
27742
|
repoRoot,
|
|
27417
|
-
title:
|
|
27743
|
+
title: path30.basename(absoluteInput) || absoluteInput
|
|
27418
27744
|
};
|
|
27419
27745
|
}
|
|
27420
27746
|
const github = normalizeGitHubRepoRootUrl(input);
|
|
@@ -27437,16 +27763,16 @@ async function resolveManagedSourceInput(rootDir, input) {
|
|
|
27437
27763
|
};
|
|
27438
27764
|
}
|
|
27439
27765
|
function directorySourceIdsFor(manifests, inputPath) {
|
|
27440
|
-
return manifests.filter((manifest) => manifest.originalPath && withinRoot2(
|
|
27766
|
+
return manifests.filter((manifest) => manifest.originalPath && withinRoot2(path30.resolve(inputPath), path30.resolve(manifest.originalPath))).map((manifest) => manifest.sourceId).sort((left, right) => left.localeCompare(right));
|
|
27441
27767
|
}
|
|
27442
27768
|
function fileSourceIdsFor(manifests, inputPath) {
|
|
27443
|
-
const absoluteInput =
|
|
27444
|
-
return manifests.filter((manifest) => manifest.originalPath &&
|
|
27769
|
+
const absoluteInput = path30.resolve(inputPath);
|
|
27770
|
+
return manifests.filter((manifest) => manifest.originalPath && path30.resolve(manifest.originalPath) === absoluteInput).map((manifest) => manifest.sourceId).sort((left, right) => left.localeCompare(right));
|
|
27445
27771
|
}
|
|
27446
27772
|
async function syncDirectorySource(rootDir, inputPath, repoRoot) {
|
|
27447
27773
|
const manifestsBefore = await listManifests(rootDir);
|
|
27448
27774
|
const previousInScope = manifestsBefore.filter(
|
|
27449
|
-
(manifest) => manifest.originalPath && withinRoot2(
|
|
27775
|
+
(manifest) => manifest.originalPath && withinRoot2(path30.resolve(inputPath), path30.resolve(manifest.originalPath))
|
|
27450
27776
|
);
|
|
27451
27777
|
const result = await ingestDirectory(rootDir, inputPath, { repoRoot });
|
|
27452
27778
|
const removed = [];
|
|
@@ -27454,7 +27780,7 @@ async function syncDirectorySource(rootDir, inputPath, repoRoot) {
|
|
|
27454
27780
|
if (!manifest.originalPath) {
|
|
27455
27781
|
continue;
|
|
27456
27782
|
}
|
|
27457
|
-
if (await fileExists(
|
|
27783
|
+
if (await fileExists(path30.resolve(manifest.originalPath))) {
|
|
27458
27784
|
continue;
|
|
27459
27785
|
}
|
|
27460
27786
|
const removedManifest = await removeManifestBySourceId(rootDir, manifest.sourceId);
|
|
@@ -27464,7 +27790,7 @@ async function syncDirectorySource(rootDir, inputPath, repoRoot) {
|
|
|
27464
27790
|
}
|
|
27465
27791
|
const manifestsAfter = await listManifests(rootDir);
|
|
27466
27792
|
return {
|
|
27467
|
-
title:
|
|
27793
|
+
title: path30.basename(inputPath) || inputPath,
|
|
27468
27794
|
sourceIds: directorySourceIdsFor(manifestsAfter, inputPath),
|
|
27469
27795
|
counts: {
|
|
27470
27796
|
scannedCount: result.scannedCount,
|
|
@@ -27480,7 +27806,7 @@ async function syncFileSource(rootDir, inputPath) {
|
|
|
27480
27806
|
const result = await ingestInputDetailed(rootDir, inputPath);
|
|
27481
27807
|
const manifestsAfter = await listManifests(rootDir);
|
|
27482
27808
|
return {
|
|
27483
|
-
title:
|
|
27809
|
+
title: path30.basename(inputPath, path30.extname(inputPath)) || inputPath,
|
|
27484
27810
|
sourceIds: fileSourceIdsFor(manifestsAfter, inputPath),
|
|
27485
27811
|
counts: {
|
|
27486
27812
|
scannedCount: result.scannedCount,
|
|
@@ -27514,8 +27840,8 @@ async function runGitCommand(cwd, args) {
|
|
|
27514
27840
|
}
|
|
27515
27841
|
async function syncGitHubRepoSource(rootDir, entry) {
|
|
27516
27842
|
const workingDir = await managedSourceWorkingDir(rootDir, entry.id);
|
|
27517
|
-
const checkoutDir =
|
|
27518
|
-
await
|
|
27843
|
+
const checkoutDir = path30.join(workingDir, "checkout");
|
|
27844
|
+
await fs26.rm(checkoutDir, { recursive: true, force: true });
|
|
27519
27845
|
await ensureDir(workingDir);
|
|
27520
27846
|
if (!entry.url) {
|
|
27521
27847
|
throw new Error(`Managed source ${entry.id} is missing its repository URL.`);
|
|
@@ -27645,7 +27971,7 @@ function scopedNodeIds(graph, sourceIds) {
|
|
|
27645
27971
|
async function loadSourceAnalyses(rootDir, sourceIds) {
|
|
27646
27972
|
const { paths } = await loadVaultConfig(rootDir);
|
|
27647
27973
|
const analyses = await Promise.all(
|
|
27648
|
-
sourceIds.map(async (sourceId) => await readJsonFile(
|
|
27974
|
+
sourceIds.map(async (sourceId) => await readJsonFile(path30.join(paths.analysesDir, `${sourceId}.json`)))
|
|
27649
27975
|
);
|
|
27650
27976
|
return analyses.filter((analysis) => Boolean(analysis?.sourceId));
|
|
27651
27977
|
}
|
|
@@ -27806,9 +28132,9 @@ async function writeSourceBriefForScope(rootDir, source) {
|
|
|
27806
28132
|
confidence: 0.82
|
|
27807
28133
|
}
|
|
27808
28134
|
});
|
|
27809
|
-
const absolutePath =
|
|
27810
|
-
await ensureDir(
|
|
27811
|
-
await
|
|
28135
|
+
const absolutePath = path30.join(paths.wikiDir, output.page.path);
|
|
28136
|
+
await ensureDir(path30.dirname(absolutePath));
|
|
28137
|
+
await fs26.writeFile(absolutePath, output.content, "utf8");
|
|
27812
28138
|
return absolutePath;
|
|
27813
28139
|
}
|
|
27814
28140
|
async function writeSourceBrief(rootDir, source) {
|
|
@@ -28096,7 +28422,7 @@ function selectGuidedTargetPages(scope, sourcePages, questions) {
|
|
|
28096
28422
|
return (matchedTargets.length ? matchedTargets : canonicalPages).slice(0, 6);
|
|
28097
28423
|
}
|
|
28098
28424
|
function insightRelativePathForTarget(page, scope) {
|
|
28099
|
-
const basename =
|
|
28425
|
+
const basename = path30.basename(page.path);
|
|
28100
28426
|
if (page.kind === "concept") {
|
|
28101
28427
|
return `insights/concepts/${basename}`;
|
|
28102
28428
|
}
|
|
@@ -28323,7 +28649,7 @@ async function stageSourceReviewForScope(rootDir, scope) {
|
|
|
28323
28649
|
return {
|
|
28324
28650
|
sourceId: scope.id,
|
|
28325
28651
|
pageId: output.page.id,
|
|
28326
|
-
reviewPath:
|
|
28652
|
+
reviewPath: path30.join(approval.approvalDir, "wiki", output.page.path),
|
|
28327
28653
|
staged: true,
|
|
28328
28654
|
approvalId: approval.approvalId,
|
|
28329
28655
|
approvalDir: approval.approvalDir
|
|
@@ -28390,7 +28716,7 @@ async function buildSourceSessionSavedPage(rootDir, scope, session) {
|
|
|
28390
28716
|
const evidenceState = contradictions.length > 0 ? "conflicting" : session.targetedPagePaths.some(
|
|
28391
28717
|
(targetPath) => sourcePages.some((page) => page.path === targetPath && page.sourceIds.some((sourceId) => !scope.sourceIds.includes(sourceId)))
|
|
28392
28718
|
) ? "reinforcing" : session.targetedPagePaths.length ? "new" : "needs_judgment";
|
|
28393
|
-
const relativeBriefPath = session.briefPath &&
|
|
28719
|
+
const relativeBriefPath = session.briefPath && path30.isAbsolute(session.briefPath) ? path30.relative(paths.wikiDir, session.briefPath) : session.briefPath;
|
|
28394
28720
|
const sessionMarkdown = [
|
|
28395
28721
|
`# Guided Session: ${scope.title}`,
|
|
28396
28722
|
"",
|
|
@@ -28473,9 +28799,9 @@ async function buildSourceSessionSavedPage(rootDir, scope, session) {
|
|
|
28473
28799
|
async function persistSourceSessionPage(rootDir, scope, session) {
|
|
28474
28800
|
const { paths } = await loadVaultConfig(rootDir);
|
|
28475
28801
|
const output = await buildSourceSessionSavedPage(rootDir, scope, session);
|
|
28476
|
-
const absolutePath =
|
|
28477
|
-
await ensureDir(
|
|
28478
|
-
await
|
|
28802
|
+
const absolutePath = path30.join(paths.wikiDir, output.page.path);
|
|
28803
|
+
await ensureDir(path30.dirname(absolutePath));
|
|
28804
|
+
await fs26.writeFile(absolutePath, output.content, "utf8");
|
|
28479
28805
|
return { pageId: output.page.id, sessionPath: absolutePath };
|
|
28480
28806
|
}
|
|
28481
28807
|
async function buildGuidedUpdatePages(rootDir, scope, session) {
|
|
@@ -28503,9 +28829,9 @@ async function buildGuidedUpdatePages(rootDir, scope, session) {
|
|
|
28503
28829
|
targetPages.map(async (targetPage) => {
|
|
28504
28830
|
const evidenceState = classifyGuidedEvidenceState(scope, targetPage, contradictions);
|
|
28505
28831
|
const relativePath = useCanonicalTargets && targetPage ? targetPage.path : targetPage ? insightRelativePathForTarget(targetPage, scope) : `insights/topics/${slugify(scope.title)}.md`;
|
|
28506
|
-
const absolutePath =
|
|
28507
|
-
const existingContent = await fileExists(absolutePath) ? await
|
|
28508
|
-
const parsed = existingContent ?
|
|
28832
|
+
const absolutePath = path30.join(paths.wikiDir, relativePath);
|
|
28833
|
+
const existingContent = await fileExists(absolutePath) ? await fs26.readFile(absolutePath, "utf8") : "";
|
|
28834
|
+
const parsed = existingContent ? matter14(existingContent) : { data: {}, content: "" };
|
|
28509
28835
|
const existingData = parsed.data;
|
|
28510
28836
|
const existingSourceIds = Array.isArray(existingData.source_ids) ? existingData.source_ids.filter((value) => typeof value === "string") : [];
|
|
28511
28837
|
const existingProjectIds = Array.isArray(existingData.project_ids) ? existingData.project_ids.filter((value) => typeof value === "string") : [];
|
|
@@ -28566,7 +28892,7 @@ async function buildGuidedUpdatePages(rootDir, scope, session) {
|
|
|
28566
28892
|
""
|
|
28567
28893
|
].join("\n");
|
|
28568
28894
|
const nextBody = replaceMarkedSection(baseBody, scope.id, updateBlock);
|
|
28569
|
-
const content =
|
|
28895
|
+
const content = matter14.stringify(
|
|
28570
28896
|
`${nextBody.trimEnd()}
|
|
28571
28897
|
`,
|
|
28572
28898
|
JSON.parse(
|
|
@@ -28675,8 +29001,8 @@ async function stageSourceGuideForScope(rootDir, scope, options = {}) {
|
|
|
28675
29001
|
}
|
|
28676
29002
|
);
|
|
28677
29003
|
session.status = "staged";
|
|
28678
|
-
session.reviewPath =
|
|
28679
|
-
session.guidePath =
|
|
29004
|
+
session.reviewPath = path30.join(approval.approvalDir, "wiki", reviewOutput.page.path);
|
|
29005
|
+
session.guidePath = path30.join(approval.approvalDir, "wiki", guideOutput.page.path);
|
|
28680
29006
|
session.approvalId = approval.approvalId;
|
|
28681
29007
|
session.approvalDir = approval.approvalDir;
|
|
28682
29008
|
const persisted = await persistSourceSessionPage(rootDir, scope, session);
|
|
@@ -28814,7 +29140,7 @@ async function addManagedSource(rootDir, input, options = {}) {
|
|
|
28814
29140
|
const existing = sources.find((candidate) => matchesManagedSourceSpec(candidate, resolved));
|
|
28815
29141
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
28816
29142
|
const source = existing ?? {
|
|
28817
|
-
id: resolved.kind === "directory" || resolved.kind === "file" ? stableManagedSourceId(resolved.kind,
|
|
29143
|
+
id: resolved.kind === "directory" || resolved.kind === "file" ? stableManagedSourceId(resolved.kind, path30.resolve(resolved.path), resolved.title) : stableManagedSourceId(resolved.kind, resolved.url, resolved.title),
|
|
28818
29144
|
kind: resolved.kind,
|
|
28819
29145
|
title: resolved.title,
|
|
28820
29146
|
path: resolved.kind === "directory" || resolved.kind === "file" ? resolved.path : void 0,
|
|
@@ -28942,7 +29268,7 @@ async function deleteManagedSource(rootDir, id) {
|
|
|
28942
29268
|
sources.filter((source) => source.id !== id)
|
|
28943
29269
|
);
|
|
28944
29270
|
const workingDir = await managedSourceWorkingDir(rootDir, id);
|
|
28945
|
-
await
|
|
29271
|
+
await fs26.rm(workingDir, { recursive: true, force: true });
|
|
28946
29272
|
return { removed: target };
|
|
28947
29273
|
}
|
|
28948
29274
|
|
|
@@ -28950,11 +29276,11 @@ async function deleteManagedSource(rootDir, id) {
|
|
|
28950
29276
|
import { execFile as execFile2 } from "child_process";
|
|
28951
29277
|
import { randomUUID } from "crypto";
|
|
28952
29278
|
import { EventEmitter } from "events";
|
|
28953
|
-
import
|
|
29279
|
+
import fs27 from "fs/promises";
|
|
28954
29280
|
import http from "http";
|
|
28955
|
-
import
|
|
29281
|
+
import path31 from "path";
|
|
28956
29282
|
import { promisify as promisify2 } from "util";
|
|
28957
|
-
import
|
|
29283
|
+
import matter15 from "gray-matter";
|
|
28958
29284
|
import mime2 from "mime-types";
|
|
28959
29285
|
|
|
28960
29286
|
// src/graph-presentation.ts
|
|
@@ -29106,7 +29432,7 @@ function toViewerLintFindings(findings) {
|
|
|
29106
29432
|
var execFileAsync2 = promisify2(execFile2);
|
|
29107
29433
|
async function isReadableFile(absolutePath) {
|
|
29108
29434
|
try {
|
|
29109
|
-
const stats = await
|
|
29435
|
+
const stats = await fs27.stat(absolutePath);
|
|
29110
29436
|
return stats.isFile();
|
|
29111
29437
|
} catch {
|
|
29112
29438
|
return false;
|
|
@@ -29117,15 +29443,15 @@ async function readViewerPage(rootDir, relativePath) {
|
|
|
29117
29443
|
return null;
|
|
29118
29444
|
}
|
|
29119
29445
|
const { paths } = await loadVaultConfig(rootDir);
|
|
29120
|
-
const absolutePath =
|
|
29446
|
+
const absolutePath = path31.resolve(paths.wikiDir, relativePath);
|
|
29121
29447
|
if (!isPathWithin(paths.wikiDir, absolutePath) || !await isReadableFile(absolutePath)) {
|
|
29122
29448
|
return null;
|
|
29123
29449
|
}
|
|
29124
|
-
const raw = await
|
|
29125
|
-
const parsed =
|
|
29450
|
+
const raw = await fs27.readFile(absolutePath, "utf8");
|
|
29451
|
+
const parsed = matter15(raw);
|
|
29126
29452
|
return {
|
|
29127
29453
|
path: relativePath,
|
|
29128
|
-
title: typeof parsed.data.title === "string" ? parsed.data.title :
|
|
29454
|
+
title: typeof parsed.data.title === "string" ? parsed.data.title : path31.basename(relativePath, path31.extname(relativePath)),
|
|
29129
29455
|
frontmatter: parsed.data,
|
|
29130
29456
|
content: parsed.content,
|
|
29131
29457
|
assets: normalizeOutputAssets(parsed.data.output_assets)
|
|
@@ -29136,12 +29462,12 @@ async function readViewerAsset(rootDir, relativePath) {
|
|
|
29136
29462
|
return null;
|
|
29137
29463
|
}
|
|
29138
29464
|
const { paths } = await loadVaultConfig(rootDir);
|
|
29139
|
-
const absolutePath =
|
|
29465
|
+
const absolutePath = path31.resolve(paths.wikiDir, relativePath);
|
|
29140
29466
|
if (!isPathWithin(paths.wikiDir, absolutePath) || !await isReadableFile(absolutePath)) {
|
|
29141
29467
|
return null;
|
|
29142
29468
|
}
|
|
29143
29469
|
return {
|
|
29144
|
-
buffer: await
|
|
29470
|
+
buffer: await fs27.readFile(absolutePath),
|
|
29145
29471
|
mimeType: mime2.lookup(absolutePath) || "application/octet-stream"
|
|
29146
29472
|
};
|
|
29147
29473
|
}
|
|
@@ -29164,12 +29490,12 @@ async function readJsonBody(request) {
|
|
|
29164
29490
|
return JSON.parse(raw);
|
|
29165
29491
|
}
|
|
29166
29492
|
async function ensureViewerDist(viewerDistDir) {
|
|
29167
|
-
const indexPath =
|
|
29493
|
+
const indexPath = path31.join(viewerDistDir, "index.html");
|
|
29168
29494
|
if (await fileExists(indexPath)) {
|
|
29169
29495
|
return;
|
|
29170
29496
|
}
|
|
29171
|
-
const viewerProjectDir =
|
|
29172
|
-
if (await fileExists(
|
|
29497
|
+
const viewerProjectDir = path31.dirname(viewerDistDir);
|
|
29498
|
+
if (await fileExists(path31.join(viewerProjectDir, "package.json"))) {
|
|
29173
29499
|
await execFileAsync2("pnpm", ["build"], { cwd: viewerProjectDir });
|
|
29174
29500
|
}
|
|
29175
29501
|
}
|
|
@@ -29192,7 +29518,7 @@ async function startGraphServer(rootDir, port, options = {}) {
|
|
|
29192
29518
|
response.end(JSON.stringify({ error: "Graph artifact not found. Run `swarmvault compile` first." }));
|
|
29193
29519
|
return;
|
|
29194
29520
|
}
|
|
29195
|
-
const reportPath =
|
|
29521
|
+
const reportPath = path31.join(paths.wikiDir, "graph", "report.json");
|
|
29196
29522
|
const report = await readJsonFile(reportPath) ?? null;
|
|
29197
29523
|
response.writeHead(200, { "content-type": "application/json" });
|
|
29198
29524
|
response.end(JSON.stringify(buildViewerGraphArtifact(graph, { report, full: options.full ?? false })));
|
|
@@ -29256,13 +29582,13 @@ async function startGraphServer(rootDir, port, options = {}) {
|
|
|
29256
29582
|
return;
|
|
29257
29583
|
}
|
|
29258
29584
|
if (url.pathname === "/api/graph-report") {
|
|
29259
|
-
const reportPath =
|
|
29585
|
+
const reportPath = path31.join(paths.wikiDir, "graph", "report.json");
|
|
29260
29586
|
if (!await fileExists(reportPath)) {
|
|
29261
29587
|
response.writeHead(404, { "content-type": "application/json" });
|
|
29262
29588
|
response.end(JSON.stringify({ error: "Graph report artifact not found. Run `swarmvault compile` first." }));
|
|
29263
29589
|
return;
|
|
29264
29590
|
}
|
|
29265
|
-
const body = await
|
|
29591
|
+
const body = await fs27.readFile(reportPath, "utf8");
|
|
29266
29592
|
response.writeHead(200, { "content-type": "application/json" });
|
|
29267
29593
|
response.end(body);
|
|
29268
29594
|
return;
|
|
@@ -29363,7 +29689,7 @@ async function startGraphServer(rootDir, port, options = {}) {
|
|
|
29363
29689
|
return;
|
|
29364
29690
|
}
|
|
29365
29691
|
if (url.pathname === "/api/workspace") {
|
|
29366
|
-
const reportPath =
|
|
29692
|
+
const reportPath = path31.join(paths.wikiDir, "graph", "report.json");
|
|
29367
29693
|
const [graphRaw, reportRaw, approvalsRaw, candidatesRaw, watchStatusRaw, lintRaw] = await Promise.all([
|
|
29368
29694
|
readJsonFile(paths.graphPath).catch(() => null),
|
|
29369
29695
|
readJsonFile(reportPath).catch(() => null),
|
|
@@ -29459,15 +29785,15 @@ async function startGraphServer(rootDir, port, options = {}) {
|
|
|
29459
29785
|
return;
|
|
29460
29786
|
}
|
|
29461
29787
|
const relativePath = url.pathname === "/" ? "index.html" : url.pathname.slice(1);
|
|
29462
|
-
const target =
|
|
29463
|
-
const fallback =
|
|
29788
|
+
const target = path31.join(paths.viewerDistDir, relativePath);
|
|
29789
|
+
const fallback = path31.join(paths.viewerDistDir, "index.html");
|
|
29464
29790
|
const filePath = await fileExists(target) ? target : fallback;
|
|
29465
29791
|
if (!await fileExists(filePath)) {
|
|
29466
29792
|
response.writeHead(503, { "content-type": "text/plain" });
|
|
29467
29793
|
response.end("Viewer build not found. Run `pnpm build` first.");
|
|
29468
29794
|
return;
|
|
29469
29795
|
}
|
|
29470
|
-
const staticBody = await
|
|
29796
|
+
const staticBody = await fs27.readFile(filePath);
|
|
29471
29797
|
response.writeHead(200, { "content-type": mime2.lookup(filePath) || "text/plain" });
|
|
29472
29798
|
response.end(staticBody);
|
|
29473
29799
|
} catch (error) {
|
|
@@ -29507,7 +29833,7 @@ async function exportGraphHtml(rootDir, outputPath, options = {}) {
|
|
|
29507
29833
|
throw new Error("Graph artifact not found. Run `swarmvault compile` first.");
|
|
29508
29834
|
}
|
|
29509
29835
|
await ensureViewerDist(paths.viewerDistDir);
|
|
29510
|
-
const indexPath =
|
|
29836
|
+
const indexPath = path31.join(paths.viewerDistDir, "index.html");
|
|
29511
29837
|
if (!await fileExists(indexPath)) {
|
|
29512
29838
|
throw new Error("Viewer build not found. Run `pnpm build` first.");
|
|
29513
29839
|
}
|
|
@@ -29533,17 +29859,17 @@ async function exportGraphHtml(rootDir, outputPath, options = {}) {
|
|
|
29533
29859
|
} : null;
|
|
29534
29860
|
})
|
|
29535
29861
|
);
|
|
29536
|
-
const rawHtml = await
|
|
29862
|
+
const rawHtml = await fs27.readFile(indexPath, "utf8");
|
|
29537
29863
|
const scriptMatch = rawHtml.match(/<script type="module" crossorigin src="([^"]+)"><\/script>/);
|
|
29538
29864
|
const styleMatch = rawHtml.match(/<link rel="stylesheet" crossorigin href="([^"]+)">/);
|
|
29539
|
-
const scriptPath = scriptMatch?.[1] ?
|
|
29540
|
-
const stylePath = styleMatch?.[1] ?
|
|
29865
|
+
const scriptPath = scriptMatch?.[1] ? path31.join(paths.viewerDistDir, scriptMatch[1].replace(/^\//, "")) : null;
|
|
29866
|
+
const stylePath = styleMatch?.[1] ? path31.join(paths.viewerDistDir, styleMatch[1].replace(/^\//, "")) : null;
|
|
29541
29867
|
if (!scriptPath || !await fileExists(scriptPath)) {
|
|
29542
29868
|
throw new Error("Viewer script bundle not found. Run `pnpm build` first.");
|
|
29543
29869
|
}
|
|
29544
|
-
const script = await
|
|
29545
|
-
const style = stylePath && await fileExists(stylePath) ? await
|
|
29546
|
-
const report = await readJsonFile(
|
|
29870
|
+
const script = await fs27.readFile(scriptPath, "utf8");
|
|
29871
|
+
const style = stylePath && await fileExists(stylePath) ? await fs27.readFile(stylePath, "utf8") : "";
|
|
29872
|
+
const report = await readJsonFile(path31.join(paths.wikiDir, "graph", "report.json"));
|
|
29547
29873
|
const embeddedData = JSON.stringify(
|
|
29548
29874
|
{ graph: buildViewerGraphArtifact(graph, { report, full: options.full ?? false }), pages: pages.filter(Boolean), report },
|
|
29549
29875
|
null,
|
|
@@ -29566,11 +29892,12 @@ async function exportGraphHtml(rootDir, outputPath, options = {}) {
|
|
|
29566
29892
|
"</html>",
|
|
29567
29893
|
""
|
|
29568
29894
|
].filter(Boolean).join("\n");
|
|
29569
|
-
await
|
|
29570
|
-
await
|
|
29571
|
-
return
|
|
29895
|
+
await fs27.mkdir(path31.dirname(outputPath), { recursive: true });
|
|
29896
|
+
await fs27.writeFile(outputPath, html, "utf8");
|
|
29897
|
+
return path31.resolve(outputPath);
|
|
29572
29898
|
}
|
|
29573
29899
|
export {
|
|
29900
|
+
ALL_MIGRATIONS,
|
|
29574
29901
|
DEFAULT_CONSOLIDATION_CONFIG,
|
|
29575
29902
|
DEFAULT_HALF_LIFE_DAYS,
|
|
29576
29903
|
DEFAULT_HALF_LIFE_DAYS_BY_SOURCE_CLASS,
|
|
@@ -29578,6 +29905,7 @@ export {
|
|
|
29578
29905
|
DEFAULT_REDACTION_PATTERNS,
|
|
29579
29906
|
DEFAULT_STALE_THRESHOLD,
|
|
29580
29907
|
LARGE_REPO_NODE_THRESHOLD,
|
|
29908
|
+
OPENAI_COMPATIBLE_CAPABILITY_MATRIX,
|
|
29581
29909
|
acceptApproval,
|
|
29582
29910
|
addInput,
|
|
29583
29911
|
addManagedSource,
|
|
@@ -29602,6 +29930,7 @@ export {
|
|
|
29602
29930
|
defaultVaultConfig,
|
|
29603
29931
|
defaultVaultSchema,
|
|
29604
29932
|
deleteManagedSource,
|
|
29933
|
+
detectVaultVersion,
|
|
29605
29934
|
estimatePageTokens,
|
|
29606
29935
|
estimateTokens,
|
|
29607
29936
|
evaluateCandidateForPromotion,
|
|
@@ -29643,9 +29972,11 @@ export {
|
|
|
29643
29972
|
loadVaultConfig,
|
|
29644
29973
|
loadVaultSchema,
|
|
29645
29974
|
loadVaultSchemas,
|
|
29975
|
+
lookupPresetCapabilities,
|
|
29646
29976
|
markSuperseded,
|
|
29647
29977
|
pathGraphVault,
|
|
29648
29978
|
persistDecayFrontmatter,
|
|
29979
|
+
planMigration,
|
|
29649
29980
|
previewCandidatePromotions,
|
|
29650
29981
|
promoteCandidate,
|
|
29651
29982
|
pushGraphNeo4j,
|
|
@@ -29671,6 +30002,7 @@ export {
|
|
|
29671
30002
|
runAutoPromotion,
|
|
29672
30003
|
runConsolidation,
|
|
29673
30004
|
runDecayPass,
|
|
30005
|
+
runMigration,
|
|
29674
30006
|
runSchedule,
|
|
29675
30007
|
runWatchCycle,
|
|
29676
30008
|
searchVault,
|
|
@@ -29683,5 +30015,6 @@ export {
|
|
|
29683
30015
|
synthesizeHyperedgeHubs,
|
|
29684
30016
|
trimToTokenBudget,
|
|
29685
30017
|
uninstallGitHooks,
|
|
29686
|
-
watchVault
|
|
30018
|
+
watchVault,
|
|
30019
|
+
withCapabilityFallback
|
|
29687
30020
|
};
|