@swarmvaultai/engine 1.0.0 → 1.1.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/chunk-UQCF65BN.js +1623 -0
- package/dist/index.d.ts +136 -1
- package/dist/index.js +249 -90
- package/dist/registry-GH4O3A7H.js +12 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
LocalWhisperProviderAdapter,
|
|
2
3
|
PRIMARY_SCHEMA_FILENAME,
|
|
3
4
|
appendJsonLine,
|
|
4
5
|
assertProviderCapability,
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
uniqueBy,
|
|
24
25
|
writeFileIfChanged,
|
|
25
26
|
writeJsonFile
|
|
26
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-UQCF65BN.js";
|
|
27
28
|
import {
|
|
28
29
|
estimatePageTokens,
|
|
29
30
|
estimateTokens,
|
|
@@ -8379,15 +8380,15 @@ function sourceTypeForNode(node, pagesById) {
|
|
|
8379
8380
|
return pagesById.get(node.pageId)?.sourceType;
|
|
8380
8381
|
}
|
|
8381
8382
|
function supportingPathDetails(graph, edge) {
|
|
8382
|
-
const
|
|
8383
|
+
const path33 = shortestGraphPath(graph, edge.source, edge.target);
|
|
8383
8384
|
const edgesById = new Map(graph.edges.map((item) => [item.id, item]));
|
|
8384
|
-
const pathEdges =
|
|
8385
|
+
const pathEdges = path33.edgeIds.map((edgeId) => edgesById.get(edgeId)).filter((item) => Boolean(item));
|
|
8385
8386
|
return {
|
|
8386
|
-
pathNodeIds:
|
|
8387
|
-
pathEdgeIds:
|
|
8387
|
+
pathNodeIds: path33.nodeIds,
|
|
8388
|
+
pathEdgeIds: path33.edgeIds,
|
|
8388
8389
|
pathRelations: pathEdges.map((item) => item.relation),
|
|
8389
8390
|
pathEvidenceClasses: pathEdges.map((item) => item.evidenceClass),
|
|
8390
|
-
pathSummary:
|
|
8391
|
+
pathSummary: path33.summary
|
|
8391
8392
|
};
|
|
8392
8393
|
}
|
|
8393
8394
|
function surpriseScore(edge, graph, pagesById, hyperedgesByNodeId) {
|
|
@@ -8456,7 +8457,7 @@ function topSurprisingConnections(graph, pagesById) {
|
|
|
8456
8457
|
}).map((edge) => {
|
|
8457
8458
|
const source = nodesById.get(edge.source);
|
|
8458
8459
|
const target = nodesById.get(edge.target);
|
|
8459
|
-
const
|
|
8460
|
+
const path33 = supportingPathDetails(graph, edge);
|
|
8460
8461
|
const scored = surpriseScore(edge, graph, pagesById, hyperedgesByNodeId);
|
|
8461
8462
|
return {
|
|
8462
8463
|
id: edge.id,
|
|
@@ -8467,11 +8468,11 @@ function topSurprisingConnections(graph, pagesById) {
|
|
|
8467
8468
|
relation: edge.relation,
|
|
8468
8469
|
evidenceClass: edge.evidenceClass,
|
|
8469
8470
|
confidence: edge.confidence,
|
|
8470
|
-
pathNodeIds:
|
|
8471
|
-
pathEdgeIds:
|
|
8472
|
-
pathRelations:
|
|
8473
|
-
pathEvidenceClasses:
|
|
8474
|
-
pathSummary:
|
|
8471
|
+
pathNodeIds: path33.pathNodeIds,
|
|
8472
|
+
pathEdgeIds: path33.pathEdgeIds,
|
|
8473
|
+
pathRelations: path33.pathRelations,
|
|
8474
|
+
pathEvidenceClasses: path33.pathEvidenceClasses,
|
|
8475
|
+
pathSummary: path33.pathSummary,
|
|
8475
8476
|
why: scored.why,
|
|
8476
8477
|
explanation: scored.explanation,
|
|
8477
8478
|
surpriseScore: scored.score
|
|
@@ -18310,7 +18311,8 @@ function isSupportedInboxKind(sourceKind) {
|
|
|
18310
18311
|
"chat_export",
|
|
18311
18312
|
"email",
|
|
18312
18313
|
"calendar",
|
|
18313
|
-
"image"
|
|
18314
|
+
"image",
|
|
18315
|
+
"audio"
|
|
18314
18316
|
].includes(sourceKind);
|
|
18315
18317
|
}
|
|
18316
18318
|
async function ingestInputDetailed(rootDir, input, options) {
|
|
@@ -20897,7 +20899,7 @@ async function resolveImageGenerationProvider(rootDir) {
|
|
|
20897
20899
|
if (!providerConfig) {
|
|
20898
20900
|
throw new Error(`No provider configured with id "${preferredProviderId}" for task "imageProvider".`);
|
|
20899
20901
|
}
|
|
20900
|
-
const { createProvider: createProvider2 } = await import("./registry-
|
|
20902
|
+
const { createProvider: createProvider2 } = await import("./registry-GH4O3A7H.js");
|
|
20901
20903
|
return createProvider2(preferredProviderId, providerConfig, rootDir);
|
|
20902
20904
|
}
|
|
20903
20905
|
async function generateOutputArtifacts(rootDir, input) {
|
|
@@ -26613,7 +26615,7 @@ async function getWatchStatus(rootDir) {
|
|
|
26613
26615
|
}
|
|
26614
26616
|
|
|
26615
26617
|
// src/mcp.ts
|
|
26616
|
-
var SERVER_VERSION = "1.
|
|
26618
|
+
var SERVER_VERSION = "1.1.0";
|
|
26617
26619
|
async function createMcpServer(rootDir) {
|
|
26618
26620
|
const server = new McpServer({
|
|
26619
26621
|
name: "swarmvault",
|
|
@@ -27149,6 +27151,155 @@ function asTextResource(uri, text) {
|
|
|
27149
27151
|
};
|
|
27150
27152
|
}
|
|
27151
27153
|
|
|
27154
|
+
// src/providers/local-whisper-setup.ts
|
|
27155
|
+
import { createWriteStream, constants as fsConstants } from "fs";
|
|
27156
|
+
import fs25 from "fs/promises";
|
|
27157
|
+
import os3 from "os";
|
|
27158
|
+
import path29 from "path";
|
|
27159
|
+
import { Readable as Readable2 } from "stream";
|
|
27160
|
+
import { pipeline } from "stream/promises";
|
|
27161
|
+
var BINARY_CANDIDATES = ["whisper-cli", "whisper-cpp", "whisper"];
|
|
27162
|
+
var HUGGINGFACE_BASE = "https://huggingface.co/ggerganov/whisper.cpp/resolve/main";
|
|
27163
|
+
var LOCAL_WHISPER_MODEL_SIZES = Object.freeze({
|
|
27164
|
+
"tiny.en": "78 MB",
|
|
27165
|
+
tiny: "78 MB",
|
|
27166
|
+
"base.en": "147 MB",
|
|
27167
|
+
base: "147 MB",
|
|
27168
|
+
"small.en": "488 MB",
|
|
27169
|
+
small: "488 MB",
|
|
27170
|
+
"medium.en": "1.5 GB",
|
|
27171
|
+
medium: "1.5 GB",
|
|
27172
|
+
"large-v3": "3.1 GB",
|
|
27173
|
+
"large-v3-turbo": "1.6 GB"
|
|
27174
|
+
});
|
|
27175
|
+
async function discoverLocalWhisperBinary(options = {}) {
|
|
27176
|
+
const env = options.env ?? process.env;
|
|
27177
|
+
if (env.SWARMVAULT_WHISPER_BINARY) {
|
|
27178
|
+
return {
|
|
27179
|
+
binaryPath: env.SWARMVAULT_WHISPER_BINARY,
|
|
27180
|
+
candidates: [env.SWARMVAULT_WHISPER_BINARY],
|
|
27181
|
+
source: "env"
|
|
27182
|
+
};
|
|
27183
|
+
}
|
|
27184
|
+
const pathValue = env.PATH ?? "";
|
|
27185
|
+
const candidates = [];
|
|
27186
|
+
for (const dir of pathValue.split(path29.delimiter)) {
|
|
27187
|
+
if (!dir) continue;
|
|
27188
|
+
for (const name of BINARY_CANDIDATES) {
|
|
27189
|
+
const full = path29.join(dir, name);
|
|
27190
|
+
candidates.push(full);
|
|
27191
|
+
if (await isExecutable(full)) {
|
|
27192
|
+
return { binaryPath: full, candidates, source: "path" };
|
|
27193
|
+
}
|
|
27194
|
+
}
|
|
27195
|
+
}
|
|
27196
|
+
return { binaryPath: null, candidates, source: "not-found" };
|
|
27197
|
+
}
|
|
27198
|
+
function expectedModelPath(modelName, homeDir) {
|
|
27199
|
+
const home = homeDir ?? os3.homedir();
|
|
27200
|
+
return path29.join(home, ".swarmvault", "models", `ggml-${modelName}.bin`);
|
|
27201
|
+
}
|
|
27202
|
+
function modelDownloadUrl(modelName) {
|
|
27203
|
+
return `${HUGGINGFACE_BASE}/ggml-${modelName}.bin`;
|
|
27204
|
+
}
|
|
27205
|
+
async function downloadWhisperModel(options) {
|
|
27206
|
+
const destPath = expectedModelPath(options.modelName, options.homeDir);
|
|
27207
|
+
await ensureDir(path29.dirname(destPath));
|
|
27208
|
+
const doFetch = options.fetchImpl ?? fetch;
|
|
27209
|
+
const url = modelDownloadUrl(options.modelName);
|
|
27210
|
+
const response = await doFetch(url);
|
|
27211
|
+
if (!response.ok) {
|
|
27212
|
+
throw new Error(`Failed to download ${url}: ${response.status} ${response.statusText}`);
|
|
27213
|
+
}
|
|
27214
|
+
if (!response.body) {
|
|
27215
|
+
throw new Error(`Response body missing for ${url}`);
|
|
27216
|
+
}
|
|
27217
|
+
const totalHeader = response.headers.get("content-length");
|
|
27218
|
+
const totalBytes = totalHeader ? Number.parseInt(totalHeader, 10) : void 0;
|
|
27219
|
+
let downloadedBytes = 0;
|
|
27220
|
+
const webStream = response.body;
|
|
27221
|
+
const source = Readable2.fromWeb(webStream);
|
|
27222
|
+
source.on("data", (chunk) => {
|
|
27223
|
+
downloadedBytes += chunk.length;
|
|
27224
|
+
options.onProgress?.({ downloadedBytes, totalBytes });
|
|
27225
|
+
});
|
|
27226
|
+
const tmpPath = `${destPath}.part`;
|
|
27227
|
+
await pipeline(source, createWriteStream(tmpPath));
|
|
27228
|
+
await fs25.rename(tmpPath, destPath);
|
|
27229
|
+
const stat = await fs25.stat(destPath);
|
|
27230
|
+
return { path: destPath, bytes: stat.size };
|
|
27231
|
+
}
|
|
27232
|
+
async function registerLocalWhisperProvider(options) {
|
|
27233
|
+
const { config, paths } = await loadVaultConfig(options.rootDir);
|
|
27234
|
+
const providerId = options.providerId ?? "local-whisper";
|
|
27235
|
+
const desired = buildProviderEntry(options);
|
|
27236
|
+
const existing = config.providers[providerId];
|
|
27237
|
+
const providerWasAdded = !existing;
|
|
27238
|
+
const providerWasUpdated = !providerWasAdded && !providerEntryMatches(existing, desired);
|
|
27239
|
+
const previousAudioProvider = config.tasks.audioProvider;
|
|
27240
|
+
const shouldSetAudio = options.setAsAudioProvider !== false && (options.setAsAudioProvider === true || !previousAudioProvider);
|
|
27241
|
+
const next = {
|
|
27242
|
+
...config,
|
|
27243
|
+
providers: {
|
|
27244
|
+
...config.providers,
|
|
27245
|
+
[providerId]: desired
|
|
27246
|
+
},
|
|
27247
|
+
tasks: {
|
|
27248
|
+
...config.tasks,
|
|
27249
|
+
audioProvider: shouldSetAudio ? providerId : previousAudioProvider
|
|
27250
|
+
}
|
|
27251
|
+
};
|
|
27252
|
+
await writeJsonFile(paths.configPath, next);
|
|
27253
|
+
return {
|
|
27254
|
+
providerId,
|
|
27255
|
+
configPath: paths.configPath,
|
|
27256
|
+
providerWasAdded,
|
|
27257
|
+
providerWasUpdated,
|
|
27258
|
+
audioProviderSet: shouldSetAudio && previousAudioProvider !== providerId,
|
|
27259
|
+
previousAudioProvider
|
|
27260
|
+
};
|
|
27261
|
+
}
|
|
27262
|
+
function buildProviderEntry(options) {
|
|
27263
|
+
const entry = {
|
|
27264
|
+
type: "local-whisper",
|
|
27265
|
+
model: options.model
|
|
27266
|
+
};
|
|
27267
|
+
if (options.binaryPath) entry.binaryPath = options.binaryPath;
|
|
27268
|
+
if (options.modelPath) entry.modelPath = options.modelPath;
|
|
27269
|
+
if (options.threads !== void 0) entry.threads = options.threads;
|
|
27270
|
+
return entry;
|
|
27271
|
+
}
|
|
27272
|
+
function providerEntryMatches(existing, desired) {
|
|
27273
|
+
return existing.type === desired.type && existing.model === desired.model && existing.binaryPath === desired.binaryPath && existing.modelPath === desired.modelPath && existing.threads === desired.threads;
|
|
27274
|
+
}
|
|
27275
|
+
async function summarizeLocalWhisperSetup(options) {
|
|
27276
|
+
const discovery = await discoverLocalWhisperBinary({ env: options.env });
|
|
27277
|
+
const modelPath = expectedModelPath(options.modelName, options.homeDir);
|
|
27278
|
+
return {
|
|
27279
|
+
binary: {
|
|
27280
|
+
found: discovery.binaryPath !== null,
|
|
27281
|
+
path: discovery.binaryPath,
|
|
27282
|
+
source: discovery.source,
|
|
27283
|
+
installHint: 'Install whisper.cpp \u2014 macOS: "brew install whisper-cpp"; Debian/Ubuntu: "sudo apt install whisper.cpp" (or build from https://github.com/ggerganov/whisper.cpp).'
|
|
27284
|
+
},
|
|
27285
|
+
model: {
|
|
27286
|
+
name: options.modelName,
|
|
27287
|
+
expectedPath: modelPath,
|
|
27288
|
+
exists: await fileExists(modelPath),
|
|
27289
|
+
downloadUrl: modelDownloadUrl(options.modelName),
|
|
27290
|
+
approximateSize: LOCAL_WHISPER_MODEL_SIZES[options.modelName]
|
|
27291
|
+
}
|
|
27292
|
+
};
|
|
27293
|
+
}
|
|
27294
|
+
async function isExecutable(p) {
|
|
27295
|
+
try {
|
|
27296
|
+
await fs25.access(p, fsConstants.X_OK);
|
|
27297
|
+
return true;
|
|
27298
|
+
} catch {
|
|
27299
|
+
return false;
|
|
27300
|
+
}
|
|
27301
|
+
}
|
|
27302
|
+
|
|
27152
27303
|
// src/providers/openai-compatible-capabilities.ts
|
|
27153
27304
|
var OPENAI_COMPATIBLE_CAPABILITY_MATRIX = Object.freeze({
|
|
27154
27305
|
openai: {
|
|
@@ -27212,13 +27363,13 @@ async function withCapabilityFallback(provider, capability, run, fallback) {
|
|
|
27212
27363
|
}
|
|
27213
27364
|
|
|
27214
27365
|
// src/schedule.ts
|
|
27215
|
-
import
|
|
27216
|
-
import
|
|
27366
|
+
import fs26 from "fs/promises";
|
|
27367
|
+
import path30 from "path";
|
|
27217
27368
|
function scheduleStatePath(schedulesDir, jobId) {
|
|
27218
|
-
return
|
|
27369
|
+
return path30.join(schedulesDir, `${encodeURIComponent(jobId)}.json`);
|
|
27219
27370
|
}
|
|
27220
27371
|
function scheduleLockPath(schedulesDir, jobId) {
|
|
27221
|
-
return
|
|
27372
|
+
return path30.join(schedulesDir, `${encodeURIComponent(jobId)}.lock`);
|
|
27222
27373
|
}
|
|
27223
27374
|
function parseEveryDuration(value) {
|
|
27224
27375
|
const match = value.trim().match(/^(\d+)(m|h|d)$/i);
|
|
@@ -27321,13 +27472,13 @@ async function acquireJobLease(rootDir, jobId) {
|
|
|
27321
27472
|
const { paths } = await loadVaultConfig(rootDir);
|
|
27322
27473
|
const leasePath = scheduleLockPath(paths.schedulesDir, jobId);
|
|
27323
27474
|
await ensureDir(paths.schedulesDir);
|
|
27324
|
-
const handle = await
|
|
27475
|
+
const handle = await fs26.open(leasePath, "wx");
|
|
27325
27476
|
await handle.writeFile(`${process.pid}
|
|
27326
27477
|
${(/* @__PURE__ */ new Date()).toISOString()}
|
|
27327
27478
|
`);
|
|
27328
27479
|
await handle.close();
|
|
27329
27480
|
return async () => {
|
|
27330
|
-
await
|
|
27481
|
+
await fs26.rm(leasePath, { force: true });
|
|
27331
27482
|
};
|
|
27332
27483
|
}
|
|
27333
27484
|
async function listSchedules(rootDir) {
|
|
@@ -27486,8 +27637,8 @@ async function serveSchedules(rootDir, pollMs = 3e4) {
|
|
|
27486
27637
|
|
|
27487
27638
|
// src/sources.ts
|
|
27488
27639
|
import { spawn as spawn2 } from "child_process";
|
|
27489
|
-
import
|
|
27490
|
-
import
|
|
27640
|
+
import fs27 from "fs/promises";
|
|
27641
|
+
import path31 from "path";
|
|
27491
27642
|
import matter14 from "gray-matter";
|
|
27492
27643
|
import { JSDOM as JSDOM3 } from "jsdom";
|
|
27493
27644
|
var DEFAULT_CRAWL_MAX_PAGES = 12;
|
|
@@ -27533,24 +27684,24 @@ function emptyManagedSourceSyncCounts() {
|
|
|
27533
27684
|
};
|
|
27534
27685
|
}
|
|
27535
27686
|
function withinRoot2(rootPath, targetPath) {
|
|
27536
|
-
const relative =
|
|
27537
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
27687
|
+
const relative = path31.relative(rootPath, targetPath);
|
|
27688
|
+
return relative === "" || !relative.startsWith("..") && !path31.isAbsolute(relative);
|
|
27538
27689
|
}
|
|
27539
27690
|
async function findNearestGitRoot3(startPath) {
|
|
27540
|
-
let current =
|
|
27691
|
+
let current = path31.resolve(startPath);
|
|
27541
27692
|
try {
|
|
27542
|
-
const stat = await
|
|
27693
|
+
const stat = await fs27.stat(current);
|
|
27543
27694
|
if (!stat.isDirectory()) {
|
|
27544
|
-
current =
|
|
27695
|
+
current = path31.dirname(current);
|
|
27545
27696
|
}
|
|
27546
27697
|
} catch {
|
|
27547
|
-
current =
|
|
27698
|
+
current = path31.dirname(current);
|
|
27548
27699
|
}
|
|
27549
27700
|
while (true) {
|
|
27550
|
-
if (await fileExists(
|
|
27701
|
+
if (await fileExists(path31.join(current, ".git"))) {
|
|
27551
27702
|
return current;
|
|
27552
27703
|
}
|
|
27553
|
-
const parent =
|
|
27704
|
+
const parent = path31.dirname(current);
|
|
27554
27705
|
if (parent === current) {
|
|
27555
27706
|
return null;
|
|
27556
27707
|
}
|
|
@@ -27624,7 +27775,7 @@ function isAllowedDocsCandidate(candidate, startUrl) {
|
|
|
27624
27775
|
if (candidate.origin !== startUrl.origin) {
|
|
27625
27776
|
return false;
|
|
27626
27777
|
}
|
|
27627
|
-
const extension =
|
|
27778
|
+
const extension = path31.extname(candidate.pathname).toLowerCase();
|
|
27628
27779
|
if (extension && extension !== ".html" && extension !== ".htm" && extension !== ".md") {
|
|
27629
27780
|
return false;
|
|
27630
27781
|
}
|
|
@@ -27713,14 +27864,14 @@ function matchesManagedSourceSpec(existing, input) {
|
|
|
27713
27864
|
return false;
|
|
27714
27865
|
}
|
|
27715
27866
|
if (input.kind === "directory" || input.kind === "file") {
|
|
27716
|
-
return
|
|
27867
|
+
return path31.resolve(existing.path ?? "") === path31.resolve(input.path);
|
|
27717
27868
|
}
|
|
27718
27869
|
return (existing.url ?? "") === input.url;
|
|
27719
27870
|
}
|
|
27720
27871
|
async function resolveManagedSourceInput(rootDir, input) {
|
|
27721
|
-
const absoluteInput =
|
|
27872
|
+
const absoluteInput = path31.resolve(rootDir, input);
|
|
27722
27873
|
if (!(input.startsWith("http://") || input.startsWith("https://"))) {
|
|
27723
|
-
const stat = await
|
|
27874
|
+
const stat = await fs27.stat(absoluteInput).catch(() => null);
|
|
27724
27875
|
if (!stat) {
|
|
27725
27876
|
throw new Error(`Source not found: ${input}`);
|
|
27726
27877
|
}
|
|
@@ -27728,7 +27879,7 @@ async function resolveManagedSourceInput(rootDir, input) {
|
|
|
27728
27879
|
return {
|
|
27729
27880
|
kind: "file",
|
|
27730
27881
|
path: absoluteInput,
|
|
27731
|
-
title:
|
|
27882
|
+
title: path31.basename(absoluteInput, path31.extname(absoluteInput)) || absoluteInput
|
|
27732
27883
|
};
|
|
27733
27884
|
}
|
|
27734
27885
|
if (!stat.isDirectory()) {
|
|
@@ -27740,7 +27891,7 @@ async function resolveManagedSourceInput(rootDir, input) {
|
|
|
27740
27891
|
kind: "directory",
|
|
27741
27892
|
path: absoluteInput,
|
|
27742
27893
|
repoRoot,
|
|
27743
|
-
title:
|
|
27894
|
+
title: path31.basename(absoluteInput) || absoluteInput
|
|
27744
27895
|
};
|
|
27745
27896
|
}
|
|
27746
27897
|
const github = normalizeGitHubRepoRootUrl(input);
|
|
@@ -27763,16 +27914,16 @@ async function resolveManagedSourceInput(rootDir, input) {
|
|
|
27763
27914
|
};
|
|
27764
27915
|
}
|
|
27765
27916
|
function directorySourceIdsFor(manifests, inputPath) {
|
|
27766
|
-
return manifests.filter((manifest) => manifest.originalPath && withinRoot2(
|
|
27917
|
+
return manifests.filter((manifest) => manifest.originalPath && withinRoot2(path31.resolve(inputPath), path31.resolve(manifest.originalPath))).map((manifest) => manifest.sourceId).sort((left, right) => left.localeCompare(right));
|
|
27767
27918
|
}
|
|
27768
27919
|
function fileSourceIdsFor(manifests, inputPath) {
|
|
27769
|
-
const absoluteInput =
|
|
27770
|
-
return manifests.filter((manifest) => manifest.originalPath &&
|
|
27920
|
+
const absoluteInput = path31.resolve(inputPath);
|
|
27921
|
+
return manifests.filter((manifest) => manifest.originalPath && path31.resolve(manifest.originalPath) === absoluteInput).map((manifest) => manifest.sourceId).sort((left, right) => left.localeCompare(right));
|
|
27771
27922
|
}
|
|
27772
27923
|
async function syncDirectorySource(rootDir, inputPath, repoRoot) {
|
|
27773
27924
|
const manifestsBefore = await listManifests(rootDir);
|
|
27774
27925
|
const previousInScope = manifestsBefore.filter(
|
|
27775
|
-
(manifest) => manifest.originalPath && withinRoot2(
|
|
27926
|
+
(manifest) => manifest.originalPath && withinRoot2(path31.resolve(inputPath), path31.resolve(manifest.originalPath))
|
|
27776
27927
|
);
|
|
27777
27928
|
const result = await ingestDirectory(rootDir, inputPath, { repoRoot });
|
|
27778
27929
|
const removed = [];
|
|
@@ -27780,7 +27931,7 @@ async function syncDirectorySource(rootDir, inputPath, repoRoot) {
|
|
|
27780
27931
|
if (!manifest.originalPath) {
|
|
27781
27932
|
continue;
|
|
27782
27933
|
}
|
|
27783
|
-
if (await fileExists(
|
|
27934
|
+
if (await fileExists(path31.resolve(manifest.originalPath))) {
|
|
27784
27935
|
continue;
|
|
27785
27936
|
}
|
|
27786
27937
|
const removedManifest = await removeManifestBySourceId(rootDir, manifest.sourceId);
|
|
@@ -27790,7 +27941,7 @@ async function syncDirectorySource(rootDir, inputPath, repoRoot) {
|
|
|
27790
27941
|
}
|
|
27791
27942
|
const manifestsAfter = await listManifests(rootDir);
|
|
27792
27943
|
return {
|
|
27793
|
-
title:
|
|
27944
|
+
title: path31.basename(inputPath) || inputPath,
|
|
27794
27945
|
sourceIds: directorySourceIdsFor(manifestsAfter, inputPath),
|
|
27795
27946
|
counts: {
|
|
27796
27947
|
scannedCount: result.scannedCount,
|
|
@@ -27806,7 +27957,7 @@ async function syncFileSource(rootDir, inputPath) {
|
|
|
27806
27957
|
const result = await ingestInputDetailed(rootDir, inputPath);
|
|
27807
27958
|
const manifestsAfter = await listManifests(rootDir);
|
|
27808
27959
|
return {
|
|
27809
|
-
title:
|
|
27960
|
+
title: path31.basename(inputPath, path31.extname(inputPath)) || inputPath,
|
|
27810
27961
|
sourceIds: fileSourceIdsFor(manifestsAfter, inputPath),
|
|
27811
27962
|
counts: {
|
|
27812
27963
|
scannedCount: result.scannedCount,
|
|
@@ -27840,8 +27991,8 @@ async function runGitCommand(cwd, args) {
|
|
|
27840
27991
|
}
|
|
27841
27992
|
async function syncGitHubRepoSource(rootDir, entry) {
|
|
27842
27993
|
const workingDir = await managedSourceWorkingDir(rootDir, entry.id);
|
|
27843
|
-
const checkoutDir =
|
|
27844
|
-
await
|
|
27994
|
+
const checkoutDir = path31.join(workingDir, "checkout");
|
|
27995
|
+
await fs27.rm(checkoutDir, { recursive: true, force: true });
|
|
27845
27996
|
await ensureDir(workingDir);
|
|
27846
27997
|
if (!entry.url) {
|
|
27847
27998
|
throw new Error(`Managed source ${entry.id} is missing its repository URL.`);
|
|
@@ -27971,7 +28122,7 @@ function scopedNodeIds(graph, sourceIds) {
|
|
|
27971
28122
|
async function loadSourceAnalyses(rootDir, sourceIds) {
|
|
27972
28123
|
const { paths } = await loadVaultConfig(rootDir);
|
|
27973
28124
|
const analyses = await Promise.all(
|
|
27974
|
-
sourceIds.map(async (sourceId) => await readJsonFile(
|
|
28125
|
+
sourceIds.map(async (sourceId) => await readJsonFile(path31.join(paths.analysesDir, `${sourceId}.json`)))
|
|
27975
28126
|
);
|
|
27976
28127
|
return analyses.filter((analysis) => Boolean(analysis?.sourceId));
|
|
27977
28128
|
}
|
|
@@ -28132,9 +28283,9 @@ async function writeSourceBriefForScope(rootDir, source) {
|
|
|
28132
28283
|
confidence: 0.82
|
|
28133
28284
|
}
|
|
28134
28285
|
});
|
|
28135
|
-
const absolutePath =
|
|
28136
|
-
await ensureDir(
|
|
28137
|
-
await
|
|
28286
|
+
const absolutePath = path31.join(paths.wikiDir, output.page.path);
|
|
28287
|
+
await ensureDir(path31.dirname(absolutePath));
|
|
28288
|
+
await fs27.writeFile(absolutePath, output.content, "utf8");
|
|
28138
28289
|
return absolutePath;
|
|
28139
28290
|
}
|
|
28140
28291
|
async function writeSourceBrief(rootDir, source) {
|
|
@@ -28422,7 +28573,7 @@ function selectGuidedTargetPages(scope, sourcePages, questions) {
|
|
|
28422
28573
|
return (matchedTargets.length ? matchedTargets : canonicalPages).slice(0, 6);
|
|
28423
28574
|
}
|
|
28424
28575
|
function insightRelativePathForTarget(page, scope) {
|
|
28425
|
-
const basename =
|
|
28576
|
+
const basename = path31.basename(page.path);
|
|
28426
28577
|
if (page.kind === "concept") {
|
|
28427
28578
|
return `insights/concepts/${basename}`;
|
|
28428
28579
|
}
|
|
@@ -28649,7 +28800,7 @@ async function stageSourceReviewForScope(rootDir, scope) {
|
|
|
28649
28800
|
return {
|
|
28650
28801
|
sourceId: scope.id,
|
|
28651
28802
|
pageId: output.page.id,
|
|
28652
|
-
reviewPath:
|
|
28803
|
+
reviewPath: path31.join(approval.approvalDir, "wiki", output.page.path),
|
|
28653
28804
|
staged: true,
|
|
28654
28805
|
approvalId: approval.approvalId,
|
|
28655
28806
|
approvalDir: approval.approvalDir
|
|
@@ -28716,7 +28867,7 @@ async function buildSourceSessionSavedPage(rootDir, scope, session) {
|
|
|
28716
28867
|
const evidenceState = contradictions.length > 0 ? "conflicting" : session.targetedPagePaths.some(
|
|
28717
28868
|
(targetPath) => sourcePages.some((page) => page.path === targetPath && page.sourceIds.some((sourceId) => !scope.sourceIds.includes(sourceId)))
|
|
28718
28869
|
) ? "reinforcing" : session.targetedPagePaths.length ? "new" : "needs_judgment";
|
|
28719
|
-
const relativeBriefPath = session.briefPath &&
|
|
28870
|
+
const relativeBriefPath = session.briefPath && path31.isAbsolute(session.briefPath) ? path31.relative(paths.wikiDir, session.briefPath) : session.briefPath;
|
|
28720
28871
|
const sessionMarkdown = [
|
|
28721
28872
|
`# Guided Session: ${scope.title}`,
|
|
28722
28873
|
"",
|
|
@@ -28799,9 +28950,9 @@ async function buildSourceSessionSavedPage(rootDir, scope, session) {
|
|
|
28799
28950
|
async function persistSourceSessionPage(rootDir, scope, session) {
|
|
28800
28951
|
const { paths } = await loadVaultConfig(rootDir);
|
|
28801
28952
|
const output = await buildSourceSessionSavedPage(rootDir, scope, session);
|
|
28802
|
-
const absolutePath =
|
|
28803
|
-
await ensureDir(
|
|
28804
|
-
await
|
|
28953
|
+
const absolutePath = path31.join(paths.wikiDir, output.page.path);
|
|
28954
|
+
await ensureDir(path31.dirname(absolutePath));
|
|
28955
|
+
await fs27.writeFile(absolutePath, output.content, "utf8");
|
|
28805
28956
|
return { pageId: output.page.id, sessionPath: absolutePath };
|
|
28806
28957
|
}
|
|
28807
28958
|
async function buildGuidedUpdatePages(rootDir, scope, session) {
|
|
@@ -28829,8 +28980,8 @@ async function buildGuidedUpdatePages(rootDir, scope, session) {
|
|
|
28829
28980
|
targetPages.map(async (targetPage) => {
|
|
28830
28981
|
const evidenceState = classifyGuidedEvidenceState(scope, targetPage, contradictions);
|
|
28831
28982
|
const relativePath = useCanonicalTargets && targetPage ? targetPage.path : targetPage ? insightRelativePathForTarget(targetPage, scope) : `insights/topics/${slugify(scope.title)}.md`;
|
|
28832
|
-
const absolutePath =
|
|
28833
|
-
const existingContent = await fileExists(absolutePath) ? await
|
|
28983
|
+
const absolutePath = path31.join(paths.wikiDir, relativePath);
|
|
28984
|
+
const existingContent = await fileExists(absolutePath) ? await fs27.readFile(absolutePath, "utf8") : "";
|
|
28834
28985
|
const parsed = existingContent ? matter14(existingContent) : { data: {}, content: "" };
|
|
28835
28986
|
const existingData = parsed.data;
|
|
28836
28987
|
const existingSourceIds = Array.isArray(existingData.source_ids) ? existingData.source_ids.filter((value) => typeof value === "string") : [];
|
|
@@ -29001,8 +29152,8 @@ async function stageSourceGuideForScope(rootDir, scope, options = {}) {
|
|
|
29001
29152
|
}
|
|
29002
29153
|
);
|
|
29003
29154
|
session.status = "staged";
|
|
29004
|
-
session.reviewPath =
|
|
29005
|
-
session.guidePath =
|
|
29155
|
+
session.reviewPath = path31.join(approval.approvalDir, "wiki", reviewOutput.page.path);
|
|
29156
|
+
session.guidePath = path31.join(approval.approvalDir, "wiki", guideOutput.page.path);
|
|
29006
29157
|
session.approvalId = approval.approvalId;
|
|
29007
29158
|
session.approvalDir = approval.approvalDir;
|
|
29008
29159
|
const persisted = await persistSourceSessionPage(rootDir, scope, session);
|
|
@@ -29140,7 +29291,7 @@ async function addManagedSource(rootDir, input, options = {}) {
|
|
|
29140
29291
|
const existing = sources.find((candidate) => matchesManagedSourceSpec(candidate, resolved));
|
|
29141
29292
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
29142
29293
|
const source = existing ?? {
|
|
29143
|
-
id: resolved.kind === "directory" || resolved.kind === "file" ? stableManagedSourceId(resolved.kind,
|
|
29294
|
+
id: resolved.kind === "directory" || resolved.kind === "file" ? stableManagedSourceId(resolved.kind, path31.resolve(resolved.path), resolved.title) : stableManagedSourceId(resolved.kind, resolved.url, resolved.title),
|
|
29144
29295
|
kind: resolved.kind,
|
|
29145
29296
|
title: resolved.title,
|
|
29146
29297
|
path: resolved.kind === "directory" || resolved.kind === "file" ? resolved.path : void 0,
|
|
@@ -29268,7 +29419,7 @@ async function deleteManagedSource(rootDir, id) {
|
|
|
29268
29419
|
sources.filter((source) => source.id !== id)
|
|
29269
29420
|
);
|
|
29270
29421
|
const workingDir = await managedSourceWorkingDir(rootDir, id);
|
|
29271
|
-
await
|
|
29422
|
+
await fs27.rm(workingDir, { recursive: true, force: true });
|
|
29272
29423
|
return { removed: target };
|
|
29273
29424
|
}
|
|
29274
29425
|
|
|
@@ -29276,9 +29427,9 @@ async function deleteManagedSource(rootDir, id) {
|
|
|
29276
29427
|
import { execFile as execFile2 } from "child_process";
|
|
29277
29428
|
import { randomUUID } from "crypto";
|
|
29278
29429
|
import { EventEmitter } from "events";
|
|
29279
|
-
import
|
|
29430
|
+
import fs28 from "fs/promises";
|
|
29280
29431
|
import http from "http";
|
|
29281
|
-
import
|
|
29432
|
+
import path32 from "path";
|
|
29282
29433
|
import { promisify as promisify2 } from "util";
|
|
29283
29434
|
import matter15 from "gray-matter";
|
|
29284
29435
|
import mime2 from "mime-types";
|
|
@@ -29432,7 +29583,7 @@ function toViewerLintFindings(findings) {
|
|
|
29432
29583
|
var execFileAsync2 = promisify2(execFile2);
|
|
29433
29584
|
async function isReadableFile(absolutePath) {
|
|
29434
29585
|
try {
|
|
29435
|
-
const stats = await
|
|
29586
|
+
const stats = await fs28.stat(absolutePath);
|
|
29436
29587
|
return stats.isFile();
|
|
29437
29588
|
} catch {
|
|
29438
29589
|
return false;
|
|
@@ -29443,15 +29594,15 @@ async function readViewerPage(rootDir, relativePath) {
|
|
|
29443
29594
|
return null;
|
|
29444
29595
|
}
|
|
29445
29596
|
const { paths } = await loadVaultConfig(rootDir);
|
|
29446
|
-
const absolutePath =
|
|
29597
|
+
const absolutePath = path32.resolve(paths.wikiDir, relativePath);
|
|
29447
29598
|
if (!isPathWithin(paths.wikiDir, absolutePath) || !await isReadableFile(absolutePath)) {
|
|
29448
29599
|
return null;
|
|
29449
29600
|
}
|
|
29450
|
-
const raw = await
|
|
29601
|
+
const raw = await fs28.readFile(absolutePath, "utf8");
|
|
29451
29602
|
const parsed = matter15(raw);
|
|
29452
29603
|
return {
|
|
29453
29604
|
path: relativePath,
|
|
29454
|
-
title: typeof parsed.data.title === "string" ? parsed.data.title :
|
|
29605
|
+
title: typeof parsed.data.title === "string" ? parsed.data.title : path32.basename(relativePath, path32.extname(relativePath)),
|
|
29455
29606
|
frontmatter: parsed.data,
|
|
29456
29607
|
content: parsed.content,
|
|
29457
29608
|
assets: normalizeOutputAssets(parsed.data.output_assets)
|
|
@@ -29462,12 +29613,12 @@ async function readViewerAsset(rootDir, relativePath) {
|
|
|
29462
29613
|
return null;
|
|
29463
29614
|
}
|
|
29464
29615
|
const { paths } = await loadVaultConfig(rootDir);
|
|
29465
|
-
const absolutePath =
|
|
29616
|
+
const absolutePath = path32.resolve(paths.wikiDir, relativePath);
|
|
29466
29617
|
if (!isPathWithin(paths.wikiDir, absolutePath) || !await isReadableFile(absolutePath)) {
|
|
29467
29618
|
return null;
|
|
29468
29619
|
}
|
|
29469
29620
|
return {
|
|
29470
|
-
buffer: await
|
|
29621
|
+
buffer: await fs28.readFile(absolutePath),
|
|
29471
29622
|
mimeType: mime2.lookup(absolutePath) || "application/octet-stream"
|
|
29472
29623
|
};
|
|
29473
29624
|
}
|
|
@@ -29490,12 +29641,12 @@ async function readJsonBody(request) {
|
|
|
29490
29641
|
return JSON.parse(raw);
|
|
29491
29642
|
}
|
|
29492
29643
|
async function ensureViewerDist(viewerDistDir) {
|
|
29493
|
-
const indexPath =
|
|
29644
|
+
const indexPath = path32.join(viewerDistDir, "index.html");
|
|
29494
29645
|
if (await fileExists(indexPath)) {
|
|
29495
29646
|
return;
|
|
29496
29647
|
}
|
|
29497
|
-
const viewerProjectDir =
|
|
29498
|
-
if (await fileExists(
|
|
29648
|
+
const viewerProjectDir = path32.dirname(viewerDistDir);
|
|
29649
|
+
if (await fileExists(path32.join(viewerProjectDir, "package.json"))) {
|
|
29499
29650
|
await execFileAsync2("pnpm", ["build"], { cwd: viewerProjectDir });
|
|
29500
29651
|
}
|
|
29501
29652
|
}
|
|
@@ -29518,7 +29669,7 @@ async function startGraphServer(rootDir, port, options = {}) {
|
|
|
29518
29669
|
response.end(JSON.stringify({ error: "Graph artifact not found. Run `swarmvault compile` first." }));
|
|
29519
29670
|
return;
|
|
29520
29671
|
}
|
|
29521
|
-
const reportPath =
|
|
29672
|
+
const reportPath = path32.join(paths.wikiDir, "graph", "report.json");
|
|
29522
29673
|
const report = await readJsonFile(reportPath) ?? null;
|
|
29523
29674
|
response.writeHead(200, { "content-type": "application/json" });
|
|
29524
29675
|
response.end(JSON.stringify(buildViewerGraphArtifact(graph, { report, full: options.full ?? false })));
|
|
@@ -29582,13 +29733,13 @@ async function startGraphServer(rootDir, port, options = {}) {
|
|
|
29582
29733
|
return;
|
|
29583
29734
|
}
|
|
29584
29735
|
if (url.pathname === "/api/graph-report") {
|
|
29585
|
-
const reportPath =
|
|
29736
|
+
const reportPath = path32.join(paths.wikiDir, "graph", "report.json");
|
|
29586
29737
|
if (!await fileExists(reportPath)) {
|
|
29587
29738
|
response.writeHead(404, { "content-type": "application/json" });
|
|
29588
29739
|
response.end(JSON.stringify({ error: "Graph report artifact not found. Run `swarmvault compile` first." }));
|
|
29589
29740
|
return;
|
|
29590
29741
|
}
|
|
29591
|
-
const body = await
|
|
29742
|
+
const body = await fs28.readFile(reportPath, "utf8");
|
|
29592
29743
|
response.writeHead(200, { "content-type": "application/json" });
|
|
29593
29744
|
response.end(body);
|
|
29594
29745
|
return;
|
|
@@ -29689,7 +29840,7 @@ async function startGraphServer(rootDir, port, options = {}) {
|
|
|
29689
29840
|
return;
|
|
29690
29841
|
}
|
|
29691
29842
|
if (url.pathname === "/api/workspace") {
|
|
29692
|
-
const reportPath =
|
|
29843
|
+
const reportPath = path32.join(paths.wikiDir, "graph", "report.json");
|
|
29693
29844
|
const [graphRaw, reportRaw, approvalsRaw, candidatesRaw, watchStatusRaw, lintRaw] = await Promise.all([
|
|
29694
29845
|
readJsonFile(paths.graphPath).catch(() => null),
|
|
29695
29846
|
readJsonFile(reportPath).catch(() => null),
|
|
@@ -29785,15 +29936,15 @@ async function startGraphServer(rootDir, port, options = {}) {
|
|
|
29785
29936
|
return;
|
|
29786
29937
|
}
|
|
29787
29938
|
const relativePath = url.pathname === "/" ? "index.html" : url.pathname.slice(1);
|
|
29788
|
-
const target =
|
|
29789
|
-
const fallback =
|
|
29939
|
+
const target = path32.join(paths.viewerDistDir, relativePath);
|
|
29940
|
+
const fallback = path32.join(paths.viewerDistDir, "index.html");
|
|
29790
29941
|
const filePath = await fileExists(target) ? target : fallback;
|
|
29791
29942
|
if (!await fileExists(filePath)) {
|
|
29792
29943
|
response.writeHead(503, { "content-type": "text/plain" });
|
|
29793
29944
|
response.end("Viewer build not found. Run `pnpm build` first.");
|
|
29794
29945
|
return;
|
|
29795
29946
|
}
|
|
29796
|
-
const staticBody = await
|
|
29947
|
+
const staticBody = await fs28.readFile(filePath);
|
|
29797
29948
|
response.writeHead(200, { "content-type": mime2.lookup(filePath) || "text/plain" });
|
|
29798
29949
|
response.end(staticBody);
|
|
29799
29950
|
} catch (error) {
|
|
@@ -29833,7 +29984,7 @@ async function exportGraphHtml(rootDir, outputPath, options = {}) {
|
|
|
29833
29984
|
throw new Error("Graph artifact not found. Run `swarmvault compile` first.");
|
|
29834
29985
|
}
|
|
29835
29986
|
await ensureViewerDist(paths.viewerDistDir);
|
|
29836
|
-
const indexPath =
|
|
29987
|
+
const indexPath = path32.join(paths.viewerDistDir, "index.html");
|
|
29837
29988
|
if (!await fileExists(indexPath)) {
|
|
29838
29989
|
throw new Error("Viewer build not found. Run `pnpm build` first.");
|
|
29839
29990
|
}
|
|
@@ -29859,17 +30010,17 @@ async function exportGraphHtml(rootDir, outputPath, options = {}) {
|
|
|
29859
30010
|
} : null;
|
|
29860
30011
|
})
|
|
29861
30012
|
);
|
|
29862
|
-
const rawHtml = await
|
|
30013
|
+
const rawHtml = await fs28.readFile(indexPath, "utf8");
|
|
29863
30014
|
const scriptMatch = rawHtml.match(/<script type="module" crossorigin src="([^"]+)"><\/script>/);
|
|
29864
30015
|
const styleMatch = rawHtml.match(/<link rel="stylesheet" crossorigin href="([^"]+)">/);
|
|
29865
|
-
const scriptPath = scriptMatch?.[1] ?
|
|
29866
|
-
const stylePath = styleMatch?.[1] ?
|
|
30016
|
+
const scriptPath = scriptMatch?.[1] ? path32.join(paths.viewerDistDir, scriptMatch[1].replace(/^\//, "")) : null;
|
|
30017
|
+
const stylePath = styleMatch?.[1] ? path32.join(paths.viewerDistDir, styleMatch[1].replace(/^\//, "")) : null;
|
|
29867
30018
|
if (!scriptPath || !await fileExists(scriptPath)) {
|
|
29868
30019
|
throw new Error("Viewer script bundle not found. Run `pnpm build` first.");
|
|
29869
30020
|
}
|
|
29870
|
-
const script = await
|
|
29871
|
-
const style = stylePath && await fileExists(stylePath) ? await
|
|
29872
|
-
const report = await readJsonFile(
|
|
30021
|
+
const script = await fs28.readFile(scriptPath, "utf8");
|
|
30022
|
+
const style = stylePath && await fileExists(stylePath) ? await fs28.readFile(stylePath, "utf8") : "";
|
|
30023
|
+
const report = await readJsonFile(path32.join(paths.wikiDir, "graph", "report.json"));
|
|
29873
30024
|
const embeddedData = JSON.stringify(
|
|
29874
30025
|
{ graph: buildViewerGraphArtifact(graph, { report, full: options.full ?? false }), pages: pages.filter(Boolean), report },
|
|
29875
30026
|
null,
|
|
@@ -29892,9 +30043,9 @@ async function exportGraphHtml(rootDir, outputPath, options = {}) {
|
|
|
29892
30043
|
"</html>",
|
|
29893
30044
|
""
|
|
29894
30045
|
].filter(Boolean).join("\n");
|
|
29895
|
-
await
|
|
29896
|
-
await
|
|
29897
|
-
return
|
|
30046
|
+
await fs28.mkdir(path32.dirname(outputPath), { recursive: true });
|
|
30047
|
+
await fs28.writeFile(outputPath, html, "utf8");
|
|
30048
|
+
return path32.resolve(outputPath);
|
|
29898
30049
|
}
|
|
29899
30050
|
export {
|
|
29900
30051
|
ALL_MIGRATIONS,
|
|
@@ -29905,6 +30056,8 @@ export {
|
|
|
29905
30056
|
DEFAULT_REDACTION_PATTERNS,
|
|
29906
30057
|
DEFAULT_STALE_THRESHOLD,
|
|
29907
30058
|
LARGE_REPO_NODE_THRESHOLD,
|
|
30059
|
+
LOCAL_WHISPER_MODEL_SIZES,
|
|
30060
|
+
LocalWhisperProviderAdapter,
|
|
29908
30061
|
OPENAI_COMPATIBLE_CAPABILITY_MATRIX,
|
|
29909
30062
|
acceptApproval,
|
|
29910
30063
|
addInput,
|
|
@@ -29931,9 +30084,12 @@ export {
|
|
|
29931
30084
|
defaultVaultSchema,
|
|
29932
30085
|
deleteManagedSource,
|
|
29933
30086
|
detectVaultVersion,
|
|
30087
|
+
discoverLocalWhisperBinary,
|
|
30088
|
+
downloadWhisperModel,
|
|
29934
30089
|
estimatePageTokens,
|
|
29935
30090
|
estimateTokens,
|
|
29936
30091
|
evaluateCandidateForPromotion,
|
|
30092
|
+
expectedModelPath,
|
|
29937
30093
|
explainGraphVault,
|
|
29938
30094
|
exploreVault,
|
|
29939
30095
|
exportGraphFormat,
|
|
@@ -29974,6 +30130,7 @@ export {
|
|
|
29974
30130
|
loadVaultSchemas,
|
|
29975
30131
|
lookupPresetCapabilities,
|
|
29976
30132
|
markSuperseded,
|
|
30133
|
+
modelDownloadUrl,
|
|
29977
30134
|
pathGraphVault,
|
|
29978
30135
|
persistDecayFrontmatter,
|
|
29979
30136
|
planMigration,
|
|
@@ -29986,6 +30143,7 @@ export {
|
|
|
29986
30143
|
readExtractedText,
|
|
29987
30144
|
readGraphReport,
|
|
29988
30145
|
readPage,
|
|
30146
|
+
registerLocalWhisperProvider,
|
|
29989
30147
|
rejectApproval,
|
|
29990
30148
|
reloadManagedSources,
|
|
29991
30149
|
removeWatchedRoot,
|
|
@@ -30010,6 +30168,7 @@ export {
|
|
|
30010
30168
|
stageGeneratedOutputPages,
|
|
30011
30169
|
startGraphServer,
|
|
30012
30170
|
startMcpServer,
|
|
30171
|
+
summarizeLocalWhisperSetup,
|
|
30013
30172
|
syncTrackedRepos,
|
|
30014
30173
|
syncTrackedReposForWatch,
|
|
30015
30174
|
synthesizeHyperedgeHubs,
|