wiki-graph-sdk 0.7.1 → 0.8.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.cjs CHANGED
@@ -32,22 +32,23 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
32
32
  var src_exports = {};
33
33
  __export(src_exports, {
34
34
  DANGEROUS_RUNTIME_ENV_NAMES: () => DANGEROUS_RUNTIME_ENV_NAMES,
35
- DEFAULT_EXTRACTION_PROMPT: () => import_wiki_graph_core8.DEFAULT_EXTRACTION_PROMPT,
35
+ DEFAULT_EXTRACTION_PROMPT: () => import_wiki_graph_core10.DEFAULT_EXTRACTION_PROMPT,
36
36
  DEFAULT_GENERATION_JOB_CONCURRENCY: () => DEFAULT_GENERATION_JOB_CONCURRENCY,
37
37
  DEFAULT_GENERATION_REQUEST_CONCURRENCY: () => DEFAULT_GENERATION_REQUEST_CONCURRENCY,
38
- DEFAULT_KNOWLEDGE_GRAPH_RECALL_PROMPT: () => import_wiki_graph_core8.DEFAULT_KNOWLEDGE_GRAPH_RECALL_PROMPT,
39
- LLMPaymentRequiredError: () => import_wiki_graph_core17.LLMPaymentRequiredError,
38
+ DEFAULT_KNOWLEDGE_GRAPH_RECALL_PROMPT: () => import_wiki_graph_core10.DEFAULT_KNOWLEDGE_GRAPH_RECALL_PROMPT,
39
+ LLMPaymentRequiredError: () => import_wiki_graph_core19.LLMPaymentRequiredError,
40
40
  LOCAL_CONFIG_SECTIONS: () => LOCAL_CONFIG_SECTIONS,
41
41
  NodeDirectory: () => NodeDirectory,
42
42
  NodeFile: () => NodeFile,
43
- WIKI_GRAPH_URI_PREFIX: () => import_wiki_graph_core17.WIKI_GRAPH_URI_PREFIX,
43
+ WIKI_GRAPH_URI_PREFIX: () => import_wiki_graph_core19.WIKI_GRAPH_URI_PREFIX,
44
44
  WikiGraphArchiveExistsError: () => WikiGraphArchiveExistsError,
45
45
  WikiGraphArchiveHandle: () => WikiGraphArchiveHandle,
46
46
  WikiGraphArchiveManager: () => WikiGraphArchiveManager,
47
+ WikiGraphArchiveOwnershipError: () => WikiGraphArchiveOwnershipError,
47
48
  WikiGraphConfigManager: () => WikiGraphConfigManager,
48
49
  WikiGraphContinuationManager: () => WikiGraphContinuationManager,
49
50
  WikiGraphConversionManager: () => WikiGraphConversionManager,
50
- WikiGraphError: () => import_wiki_graph_core17.WikiGraphError,
51
+ WikiGraphError: () => import_wiki_graph_core19.WikiGraphError,
51
52
  WikiGraphJob: () => WikiGraphJob,
52
53
  WikiGraphJobManager: () => WikiGraphJobManager,
53
54
  WikiGraphLibrary: () => WikiGraphLibrary,
@@ -62,51 +63,50 @@ __export(src_exports, {
62
63
  createNodeTemplateEnvironment: () => createNodeTemplateEnvironment,
63
64
  createNodeWikiGraphStorage: () => createNodeWikiGraphStorage,
64
65
  createStageLLM: () => createStageLLM,
65
- createWikiGraphArchiveInspectReport: () => createWikiGraphArchiveInspectReport,
66
66
  createWikiGraphSDK: () => createWikiGraphSDK,
67
67
  deleteLocalConfigValue: () => deleteLocalConfigValue,
68
68
  embedQueryText: () => embedQueryText,
69
69
  embedQueryTextWithLocalConfig: () => embedQueryTextWithLocalConfig,
70
70
  ensureNodeWikiGraphPlatform: () => ensureNodeWikiGraphPlatform,
71
- formatError: () => import_wiki_graph_core17.formatError,
71
+ formatError: () => import_wiki_graph_core19.formatError,
72
72
  formatGenerationPlanningDuration: () => formatGenerationPlanningDuration,
73
73
  formatGenerationPlanningModel: () => formatGenerationPlanningModel,
74
- formatLocatedChapterResourceUri: () => import_wiki_graph_core17.formatLocatedChapterResourceUri,
75
- formatLocatedChapterSourceCollectionUri: () => import_wiki_graph_core17.formatLocatedChapterSourceCollectionUri,
76
- formatLocatedChapterUri: () => import_wiki_graph_core17.formatLocatedChapterUri,
77
- formatLocatedWikiGraphUri: () => import_wiki_graph_core17.formatLocatedWikiGraphUri,
78
- formatWikiGraphCommandUri: () => import_wiki_graph_core17.formatWikiGraphCommandUri,
79
- formatWikiGraphLibraryUri: () => import_wiki_graph_core17.formatWikiGraphLibraryUri,
74
+ formatLocatedChapterResourceUri: () => import_wiki_graph_core19.formatLocatedChapterResourceUri,
75
+ formatLocatedChapterSourceCollectionUri: () => import_wiki_graph_core19.formatLocatedChapterSourceCollectionUri,
76
+ formatLocatedChapterUri: () => import_wiki_graph_core19.formatLocatedChapterUri,
77
+ formatLocatedWikiGraphUri: () => import_wiki_graph_core19.formatLocatedWikiGraphUri,
78
+ formatWikiGraphCommandUri: () => import_wiki_graph_core19.formatWikiGraphCommandUri,
79
+ formatWikiGraphLibraryUri: () => import_wiki_graph_core19.formatWikiGraphLibraryUri,
80
80
  getNodeResourcePath: () => getNodeResourcePath,
81
81
  getWikiGraphSDKRuntimeContext: () => getWikiGraphSDKRuntimeContext,
82
82
  getWikiGraphSDKStateDir: () => getWikiGraphSDKStateDir,
83
+ inspectWikiGraphArchive: () => inspectWikiGraphArchive,
83
84
  installNodeWikiGraphPlatform: () => installNodeWikiGraphPlatform,
84
- isSourceLocatorScopeUri: () => import_wiki_graph_core17.isSourceLocatorScopeUri,
85
- isWikiGraphLibraryUri: () => import_wiki_graph_core17.isWikiGraphLibraryUri,
85
+ isSourceLocatorScopeUri: () => import_wiki_graph_core19.isSourceLocatorScopeUri,
86
+ isWikiGraphLibraryUri: () => import_wiki_graph_core19.isWikiGraphLibraryUri,
86
87
  loadRequiredStageConfig: () => loadRequiredStageConfig,
87
88
  loadWikiGraphRuntimeConfig: () => loadWikiGraphRuntimeConfig,
88
89
  maskLocalConfigSection: () => maskLocalConfigSection,
89
90
  nodeWikiGraphPlatform: () => nodeWikiGraphPlatform,
90
91
  nodeWikispineCommandRunner: () => nodeWikispineCommandRunner,
91
92
  normalizeLocalConfigKey: () => normalizeLocalConfigKey,
92
- parseChapterPath: () => import_wiki_graph_core17.parseChapterPath,
93
- parseChapterTreeInput: () => import_wiki_graph_core17.parseChapterTreeInput,
94
- parseChapterUriPath: () => import_wiki_graph_core17.parseChapterUriPath,
93
+ parseChapterPath: () => import_wiki_graph_core19.parseChapterPath,
94
+ parseChapterTreeInput: () => import_wiki_graph_core19.parseChapterTreeInput,
95
+ parseChapterUriPath: () => import_wiki_graph_core19.parseChapterUriPath,
95
96
  parseLocalConfigSection: () => parseLocalConfigSection,
96
- parseLocatedWikiGraphUri: () => import_wiki_graph_core17.parseLocatedWikiGraphUri,
97
- parseSourceTextJsonl: () => import_wiki_graph_core17.parseSourceTextJsonl,
98
- parseWikiGraphLibraryUri: () => import_wiki_graph_core17.parseWikiGraphLibraryUri,
99
- parseWikiGraphUriSyntax: () => import_wiki_graph_core17.parseWikiGraphUriSyntax,
97
+ parseLocatedWikiGraphUri: () => import_wiki_graph_core19.parseLocatedWikiGraphUri,
98
+ parseSourceTextJsonl: () => import_wiki_graph_core19.parseSourceTextJsonl,
99
+ parseWikiGraphLibraryUri: () => import_wiki_graph_core19.parseWikiGraphLibraryUri,
100
+ parseWikiGraphUriSyntax: () => import_wiki_graph_core19.parseWikiGraphUriSyntax,
100
101
  planGenerationTask: () => planGenerationTask,
101
102
  putLocalConfigValue: () => putLocalConfigValue,
102
103
  readLocalConfigSection: () => readLocalConfigSection,
103
104
  readWikiGraphEmbeddingConfig: () => readWikiGraphEmbeddingConfig,
104
105
  replaceLocalConfigSection: () => replaceLocalConfigSection,
105
106
  requireKnowledgeGraphWikispineConfig: () => requireKnowledgeGraphWikispineConfig,
106
- resolveExtractionPrompt: () => import_wiki_graph_core8.resolveExtractionPrompt,
107
+ resolveExtractionPrompt: () => import_wiki_graph_core10.resolveExtractionPrompt,
107
108
  resolveHostedProviderEndpoint: () => resolveHostedProviderEndpoint,
108
- resolveKnowledgeGraphRecallPrompt: () => import_wiki_graph_core8.resolveKnowledgeGraphRecallPrompt,
109
- resolveWikiGraphArchiveLocation: () => resolveWikiGraphArchiveLocation,
109
+ resolveKnowledgeGraphRecallPrompt: () => import_wiki_graph_core10.resolveKnowledgeGraphRecallPrompt,
110
110
  resolveWikispineConfig: () => resolveWikispineConfig,
111
111
  runWikiGraphQueueWorker: () => runWikiGraphQueueWorker,
112
112
  validateLocalConfigSection: () => validateLocalConfigSection,
@@ -118,18 +118,18 @@ module.exports = __toCommonJS(src_exports);
118
118
 
119
119
  // src/archive/archive.ts
120
120
  var import_crypto2 = require("crypto");
121
- var import_promises3 = require("fs/promises");
121
+ var import_promises4 = require("fs/promises");
122
122
  var import_os3 = require("os");
123
- var import_path4 = require("path");
123
+ var import_path5 = require("path");
124
124
  var import_stream = require("stream");
125
- var import_wiki_graph_core5 = require("wiki-graph-core");
125
+ var import_wiki_graph_core7 = require("wiki-graph-core");
126
126
 
127
127
  // src/conversions.ts
128
128
  var import_crypto = require("crypto");
129
129
  var import_fs = require("fs");
130
- var import_promises2 = require("fs/promises");
131
- var import_path3 = require("path");
132
- var import_wiki_graph_core2 = require("wiki-graph-core");
130
+ var import_promises3 = require("fs/promises");
131
+ var import_path4 = require("path");
132
+ var import_wiki_graph_core3 = require("wiki-graph-core");
133
133
 
134
134
  // src/llm.ts
135
135
  var import_anthropic = require("@ai-sdk/anthropic");
@@ -449,42 +449,42 @@ var NodeDatabaseConnection = class {
449
449
  }
450
450
  database;
451
451
  async close() {
452
- await new Promise((resolve3, reject) => {
452
+ await new Promise((resolve4, reject) => {
453
453
  this.database.close((error) => {
454
454
  if (error) reject(error);
455
- else resolve3();
455
+ else resolve4();
456
456
  });
457
457
  });
458
458
  }
459
459
  async execute(sql) {
460
- await new Promise((resolve3, reject) => {
460
+ await new Promise((resolve4, reject) => {
461
461
  this.database.exec(sql, (error) => {
462
462
  if (error) reject(error);
463
- else resolve3();
463
+ else resolve4();
464
464
  });
465
465
  });
466
466
  }
467
467
  async queryAll(sql, params = []) {
468
- return await new Promise((resolve3, reject) => {
468
+ return await new Promise((resolve4, reject) => {
469
469
  this.database.all(sql, [...params], (error, rows) => {
470
470
  if (error) reject(error);
471
- else resolve3(rows);
471
+ else resolve4(rows);
472
472
  });
473
473
  });
474
474
  }
475
475
  async queryOne(sql, params = []) {
476
- return await new Promise((resolve3, reject) => {
476
+ return await new Promise((resolve4, reject) => {
477
477
  this.database.get(sql, [...params], (error, row) => {
478
478
  if (error) reject(error);
479
- else resolve3(row);
479
+ else resolve4(row);
480
480
  });
481
481
  });
482
482
  }
483
483
  async run(sql, params = []) {
484
- await new Promise((resolve3, reject) => {
484
+ await new Promise((resolve4, reject) => {
485
485
  this.database.run(sql, [...params], (error) => {
486
486
  if (error) reject(error);
487
- else resolve3();
487
+ else resolve4();
488
488
  });
489
489
  });
490
490
  }
@@ -498,10 +498,10 @@ async function openNativeNodeDatabase(file, flags) {
498
498
  if (path === void 0) {
499
499
  throw new TypeError("The Node database adapter requires a NodeFile");
500
500
  }
501
- return await new Promise((resolve3, reject) => {
501
+ return await new Promise((resolve4, reject) => {
502
502
  const database = new nodeSqlite3.Database(path, flags, (error) => {
503
503
  if (error) reject(error);
504
- else resolve3(database);
504
+ else resolve4(database);
505
505
  });
506
506
  });
507
507
  }
@@ -510,19 +510,19 @@ async function openNodeZip(file) {
510
510
  if (path === void 0) {
511
511
  throw new TypeError("The Node ZIP adapter requires a NodeFile");
512
512
  }
513
- const zipFile = await new Promise((resolve3, reject) => {
513
+ const zipFile = await new Promise((resolve4, reject) => {
514
514
  yauzl.open(
515
515
  path,
516
516
  { autoClose: false, lazyEntries: true },
517
517
  (error, opened) => {
518
518
  if (error || opened === void 0)
519
519
  reject(error ?? new Error("Cannot open ZIP"));
520
- else resolve3(opened);
520
+ else resolve4(opened);
521
521
  }
522
522
  );
523
523
  });
524
524
  const entries = await new Promise(
525
- (resolve3, reject) => {
525
+ (resolve4, reject) => {
526
526
  const discovered = /* @__PURE__ */ new Map();
527
527
  const rejectAndClose = (error) => {
528
528
  zipFile.close();
@@ -532,7 +532,7 @@ async function openNodeZip(file) {
532
532
  };
533
533
  const resolveEntries = () => {
534
534
  zipFile.off("error", rejectAndClose);
535
- resolve3(discovered);
535
+ resolve4(discovered);
536
536
  };
537
537
  zipFile.on("entry", (entry) => {
538
538
  if (!entry.fileName.endsWith("/")) {
@@ -642,12 +642,12 @@ async function collectDecodedNodeStreamRange(input, offset, length) {
642
642
  return Buffer.concat(chunks, collected);
643
643
  }
644
644
  async function openNodeZipEntryStream(zipFile, entry, options) {
645
- return await new Promise((resolve3, reject) => {
645
+ return await new Promise((resolve4, reject) => {
646
646
  const callback = (error, opened) => {
647
647
  if (error || opened === void 0) {
648
648
  reject(error ?? new Error(`Cannot read ZIP entry: ${entry.fileName}`));
649
649
  } else {
650
- resolve3(opened);
650
+ resolve4(opened);
651
651
  }
652
652
  };
653
653
  if (options === void 0) zipFile.openReadStream(entry, callback);
@@ -778,11 +778,11 @@ async function writeNodeStream(input, writer) {
778
778
  );
779
779
  }
780
780
  async function collectNodeStream(input) {
781
- return await new Promise((resolve3, reject) => {
781
+ return await new Promise((resolve4, reject) => {
782
782
  const chunks = [];
783
783
  input.on("data", (chunk) => chunks.push(chunk));
784
784
  input.once("error", reject);
785
- input.once("end", () => resolve3(Buffer.concat(chunks)));
785
+ input.once("end", () => resolve4(Buffer.concat(chunks)));
786
786
  });
787
787
  }
788
788
  var nodeWikiGraphPlatform = {
@@ -1451,6 +1451,194 @@ function resolveWikiGraphRuntimePath(path) {
1451
1451
  return (0, import_path2.isAbsolute)(path) ? path : (0, import_path2.resolve)(context.cwd, path);
1452
1452
  }
1453
1453
 
1454
+ // src/archive/target.ts
1455
+ var import_promises2 = require("fs/promises");
1456
+ var import_path3 = require("path");
1457
+ var import_wiki_graph_core2 = require("wiki-graph-core");
1458
+ var WikiGraphArchiveOwnershipError = class extends Error {
1459
+ code = "WIKI_GRAPH_ARCHIVE_OWNERSHIP_MISMATCH";
1460
+ constructor(message) {
1461
+ super(message);
1462
+ this.name = "WikiGraphArchiveOwnershipError";
1463
+ }
1464
+ };
1465
+ async function resolveWikiGraphArchiveLocation(target) {
1466
+ if (target.kind === "standalone") {
1467
+ return await resolveStandaloneLocation(target);
1468
+ }
1469
+ return await resolveLibraryLocation(target);
1470
+ }
1471
+ async function assertStandaloneWikiGraphArchivePath(inputPath) {
1472
+ const path = resolveWikiGraphRuntimePath(inputPath);
1473
+ const candidate = await canonicalPath(path);
1474
+ const candidateIdentity = await readFileIdentity(path);
1475
+ const libraries = await (0, import_wiki_graph_core2.listWikiGraphLibraries)();
1476
+ const matches = await findMatchingMembers(
1477
+ libraries,
1478
+ candidate,
1479
+ candidateIdentity
1480
+ );
1481
+ if (matches.length > 0) {
1482
+ const match = requireUnambiguousManagedMatch(path, matches);
1483
+ throw new WikiGraphArchiveOwnershipError(
1484
+ `Standalone archive path belongs to registered library ${(0, import_wiki_graph_core2.formatWikiGraphLibraryUri)(
1485
+ match.library.isDefault ? void 0 : match.library.publicId
1486
+ )}: ${path}. Use the library UUID URI ${match.archive.uri} instead.`
1487
+ );
1488
+ }
1489
+ for (const library of libraries) {
1490
+ const rootPath = getNodeResourcePath(library.folder);
1491
+ const root = await canonicalPath(rootPath);
1492
+ if (!isWithin(root, candidate)) continue;
1493
+ throw new WikiGraphArchiveOwnershipError(
1494
+ `Standalone archive path belongs to registered library ${(0, import_wiki_graph_core2.formatWikiGraphLibraryUri)(
1495
+ library.isDefault ? void 0 : library.publicId
1496
+ )}: ${path}. Scan the library, then address the archive by its library UUID URI.`
1497
+ );
1498
+ }
1499
+ return path;
1500
+ }
1501
+ function archiveTargetFromLogicalLocator(locator, objectUri) {
1502
+ if (locator.startsWith("wikg://lib/")) {
1503
+ return { kind: "library", uri: withObjectUri(locator, objectUri) };
1504
+ }
1505
+ return {
1506
+ kind: "standalone",
1507
+ path: locator,
1508
+ ...objectUri === void 0 ? {} : { objectUri }
1509
+ };
1510
+ }
1511
+ async function resolveWikiGraphArchiveTarget(file) {
1512
+ const path = getNodeResourcePath(file);
1513
+ const candidate = await canonicalPath(path);
1514
+ const candidateIdentity = await readFileIdentity(path);
1515
+ const matches = await findMatchingMembers(
1516
+ await (0, import_wiki_graph_core2.listWikiGraphLibraries)(),
1517
+ candidate,
1518
+ candidateIdentity
1519
+ );
1520
+ if (matches.length > 0) {
1521
+ const match = requireUnambiguousManagedMatch(path, matches);
1522
+ return { kind: "library", uri: match.archive.uri };
1523
+ }
1524
+ return { kind: "standalone", path: getNodeResourcePath(file) };
1525
+ }
1526
+ async function resolveStandaloneLocation(target) {
1527
+ if (target.path.startsWith("wikg://lib/")) {
1528
+ throw new WikiGraphArchiveOwnershipError(
1529
+ `A library archive URI cannot be used as a standalone path: ${target.path}`
1530
+ );
1531
+ }
1532
+ const path = await assertStandaloneWikiGraphArchivePath(target.path);
1533
+ const normalized = {
1534
+ kind: "standalone",
1535
+ path,
1536
+ ...target.objectUri === void 0 ? {} : { objectUri: target.objectUri }
1537
+ };
1538
+ return {
1539
+ archiveFile: new NodeFile(path),
1540
+ archiveKey: path,
1541
+ archivePath: path,
1542
+ indexScope: { archiveKey: path, archivePath: path, kind: "archive-index" },
1543
+ locatedUri: (0, import_wiki_graph_core2.formatLocatedWikiGraphUri)(path, target.objectUri),
1544
+ target: normalized
1545
+ };
1546
+ }
1547
+ async function resolveLibraryLocation(target) {
1548
+ const parsedLocated = (0, import_wiki_graph_core2.parseLocatedWikiGraphUri)(target.uri);
1549
+ const archiveUri = parsedLocated.archivePath ?? target.uri;
1550
+ const parsed = (0, import_wiki_graph_core2.parseWikiGraphLibraryUri)(archiveUri);
1551
+ if (parsed?.kind !== "archive") {
1552
+ throw new WikiGraphArchiveOwnershipError(
1553
+ `Library archive target must be a UUID archive URI: ${target.uri}`
1554
+ );
1555
+ }
1556
+ await (0, import_wiki_graph_core2.resolveWikiGraphLibrary)(parsed);
1557
+ const archiveFile = await (0, import_wiki_graph_core2.resolveWikiGraphLibraryArchiveFile)(archiveUri);
1558
+ const normalized = {
1559
+ kind: "library",
1560
+ uri: target.uri
1561
+ };
1562
+ return {
1563
+ archiveFile,
1564
+ archiveKey: archiveUri,
1565
+ archivePath: archiveUri,
1566
+ indexScope: {
1567
+ archiveKey: archiveUri,
1568
+ archivePath: archiveUri,
1569
+ kind: "archive-index"
1570
+ },
1571
+ libraryArchiveTarget: parsed,
1572
+ locatedUri: target.uri,
1573
+ publicArchiveUri: archiveUri,
1574
+ target: normalized
1575
+ };
1576
+ }
1577
+ function withObjectUri(archiveLocator, objectUri) {
1578
+ if (objectUri === void 0) return archiveLocator;
1579
+ const path = objectUri.replace(/^wikg:\/\//u, "");
1580
+ return `${archiveLocator.replace(/\/$/u, "")}/${path}`;
1581
+ }
1582
+ async function canonicalPath(path) {
1583
+ try {
1584
+ return await (0, import_promises2.realpath)(path);
1585
+ } catch {
1586
+ const absolute = (0, import_path3.resolve)(path);
1587
+ const parent = (0, import_path3.dirname)(absolute);
1588
+ return parent === absolute ? absolute : (0, import_path3.join)(await canonicalPath(parent), (0, import_path3.basename)(absolute));
1589
+ }
1590
+ }
1591
+ function isWithin(root, candidate) {
1592
+ const child = (0, import_path3.relative)(root, candidate);
1593
+ return child === "" || !child.startsWith("..") && !(0, import_path3.isAbsolute)(child);
1594
+ }
1595
+ async function findMatchingMembers(libraries, candidate, candidateIdentity) {
1596
+ const members = [];
1597
+ for (const library of libraries) {
1598
+ const archives = await (0, import_wiki_graph_core2.listWikiGraphLibraryArchives)({
1599
+ isDefault: library.isDefault,
1600
+ kind: "scope",
1601
+ ...library.isDefault ? {} : { publicId: library.publicId }
1602
+ });
1603
+ for (const archive of archives) {
1604
+ if (archive.file === void 0) continue;
1605
+ members.push({
1606
+ archive,
1607
+ library,
1608
+ memberPath: getNodeResourcePath(archive.file)
1609
+ });
1610
+ }
1611
+ }
1612
+ const exact = [];
1613
+ for (const member of members) {
1614
+ if (await canonicalPath(member.memberPath) === candidate) {
1615
+ exact.push(member);
1616
+ }
1617
+ }
1618
+ if (exact.length > 0 || candidateIdentity === void 0) return exact;
1619
+ const identityMatches = [];
1620
+ for (const member of members) {
1621
+ if (await readFileIdentity(member.memberPath) === candidateIdentity) {
1622
+ identityMatches.push(member);
1623
+ }
1624
+ }
1625
+ return identityMatches;
1626
+ }
1627
+ function requireUnambiguousManagedMatch(path, matches) {
1628
+ if (matches.length === 1) return matches[0];
1629
+ throw new WikiGraphArchiveOwnershipError(
1630
+ `Archive file identity is ambiguous across managed archives: ${path}. Use an explicit library UUID URI (${matches.map((match) => match.archive.uri).join(", ")}).`
1631
+ );
1632
+ }
1633
+ async function readFileIdentity(path) {
1634
+ try {
1635
+ const value = await (0, import_promises2.stat)(path);
1636
+ return `${value.dev}:${value.ino}`;
1637
+ } catch {
1638
+ return void 0;
1639
+ }
1640
+ }
1641
+
1454
1642
  // src/conversions.ts
1455
1643
  var WikiGraphConversionManager = class {
1456
1644
  #runtime;
@@ -1478,7 +1666,7 @@ var WikiGraphConversionManager = class {
1478
1666
  const config = await loadWikiGraphRuntimeConfig({
1479
1667
  ...options.llmJSON === void 0 ? {} : { llmJSON: options.llmJSON }
1480
1668
  });
1481
- const app = new import_wiki_graph_core2.WikiGraph({
1669
+ const app = new import_wiki_graph_core3.WikiGraph({
1482
1670
  ...options.verbose === true ? { verbose: true } : {},
1483
1671
  ...requiresLLM ? { llm: buildWikiGraphLLMOptions(config) } : {}
1484
1672
  });
@@ -1487,11 +1675,15 @@ var WikiGraphConversionManager = class {
1487
1675
  requiresDigest
1488
1676
  );
1489
1677
  let chapterCount;
1678
+ let chapterPaths;
1490
1679
  const write = async (archive) => {
1491
1680
  if (requiresDigest) await options.onSourceImported?.();
1492
1681
  if (typeof archive.readToc === "function") {
1493
1682
  const toc = await archive.readToc();
1494
1683
  chapterCount = toc === void 0 ? void 0 : countTocChapters(toc.items);
1684
+ if (options.output.format === "wikg") {
1685
+ chapterPaths = toc === void 0 ? [] : collectTocChapterPaths(toc.items);
1686
+ }
1495
1687
  }
1496
1688
  await writeArchive(archive, options.output.path, options.output.format);
1497
1689
  };
@@ -1500,7 +1692,9 @@ var WikiGraphConversionManager = class {
1500
1692
  throw new Error("wikg input requires a file path.");
1501
1693
  }
1502
1694
  await app.openSession(
1503
- new NodeFile(resolveWikiGraphRuntimePath(options.input.path)),
1695
+ new NodeFile(
1696
+ await assertStandaloneWikiGraphArchivePath(options.input.path)
1697
+ ),
1504
1698
  write
1505
1699
  );
1506
1700
  } else if ("stream" in options.input) {
@@ -1543,6 +1737,7 @@ var WikiGraphConversionManager = class {
1543
1737
  const sourceArtifact = await resolveSourceArtifact(options.input);
1544
1738
  return {
1545
1739
  ...chapterCount === void 0 ? {} : { chapterCount },
1740
+ ...chapterPaths === void 0 ? {} : { chapterPaths },
1546
1741
  inputFormat: options.input.format,
1547
1742
  outputFormat: options.output.format,
1548
1743
  outputPath: options.output.path,
@@ -1555,11 +1750,12 @@ async function prepareDigestDirectory(path, required) {
1555
1750
  if (!required || normalized === void 0 || normalized === "")
1556
1751
  return void 0;
1557
1752
  const resolved = resolveWikiGraphRuntimePath(normalized);
1558
- await (0, import_promises2.rm)(resolved, { force: true, recursive: true });
1753
+ await (0, import_promises3.rm)(resolved, { force: true, recursive: true });
1559
1754
  return new NodeDirectory(resolved);
1560
1755
  }
1561
1756
  async function writeArchive(archive, path, format) {
1562
- const file = new NodeFile(resolveWikiGraphRuntimePath(path));
1757
+ const outputPath = format === "wikg" ? await assertStandaloneWikiGraphArchivePath(path) : resolveWikiGraphRuntimePath(path);
1758
+ const file = new NodeFile(outputPath);
1563
1759
  if (format === "epub") await archive.exportEpub(file);
1564
1760
  else if (format === "wikg") await archive.saveAs(file);
1565
1761
  else if (format === "pcex") throw new Error("pcex output is not supported.");
@@ -1588,7 +1784,7 @@ async function resolveSourceArtifact(input) {
1588
1784
  return {
1589
1785
  digest: hash.digest("hex"),
1590
1786
  mediaType: "application/epub+zip",
1591
- name: (0, import_path3.basename)(path)
1787
+ name: (0, import_path4.basename)(path)
1592
1788
  };
1593
1789
  }
1594
1790
  function isNodeErrorCode(error, code) {
@@ -1604,9 +1800,24 @@ function countTocChapters(items) {
1604
1800
  }
1605
1801
  return count;
1606
1802
  }
1803
+ function collectTocChapterPaths(items, ancestorKeys = []) {
1804
+ const paths = [];
1805
+ for (const item of items) {
1806
+ const key = item.key ?? `chapter-${item.serialId ?? "group"}`;
1807
+ const chapterPath = [...ancestorKeys, key];
1808
+ if (item.serialId !== void 0) paths.push(chapterPath.join("/"));
1809
+ paths.push(
1810
+ ...collectTocChapterPaths(
1811
+ item.children,
1812
+ chapterPath
1813
+ )
1814
+ );
1815
+ }
1816
+ return paths;
1817
+ }
1607
1818
 
1608
1819
  // src/query-runtime.ts
1609
- var import_wiki_graph_core3 = require("wiki-graph-core");
1820
+ var import_wiki_graph_core4 = require("wiki-graph-core");
1610
1821
 
1611
1822
  // src/embedding.ts
1612
1823
  var import_ai = require("ai");
@@ -1779,7 +1990,7 @@ async function createConfiguredEmbeddingProvider() {
1779
1990
  async function withConfiguredWikimediaResolver(objectUri, operation) {
1780
1991
  if (!objectUri.endsWith("/wikipage")) return await operation({});
1781
1992
  const config = await loadWikiGraphRuntimeConfig();
1782
- const resolver = await (0, import_wiki_graph_core3.openWikimediaResolver)(
1993
+ const resolver = await (0, import_wiki_graph_core4.openWikimediaResolver)(
1783
1994
  config.wikimedia === void 0 ? { kind: "local" } : {
1784
1995
  endpoint: config.wikimedia.endpoint,
1785
1996
  kind: "remote",
@@ -1794,500 +2005,128 @@ async function withConfiguredWikimediaResolver(objectUri, operation) {
1794
2005
  }
1795
2006
 
1796
2007
  // src/archive/inspect.ts
1797
- var import_wiki_graph_core4 = require("wiki-graph-core");
1798
-
1799
- // src/planning.ts
1800
- var DEFAULT_GENERATION_JOB_CONCURRENCY = 3;
1801
- var DEFAULT_GENERATION_REQUEST_CONCURRENCY = 6;
1802
- function planGenerationTask(task, words, chapters, concurrent, model) {
1803
- const profile = getGenerationPlanningProfile(task);
1804
- const calls = Math.max(chapters, Math.ceil(words / profile.wordsPerCall));
1805
- const effectiveConcurrency = Math.max(
1806
- 1,
1807
- task === "reading-graph" ? 1 : concurrent.request
1808
- );
1809
- const callBatches = Math.ceil(calls / effectiveConcurrency);
1810
- const wordSeconds = words * profile.secondsPerWord;
1811
- return {
1812
- model,
1813
- timeSeconds: {
1814
- max: Math.ceil(callBatches * profile.maxSecondsPerCall + wordSeconds),
1815
- min: Math.ceil(callBatches * profile.minSecondsPerCall + wordSeconds)
1816
- },
1817
- tokens: {
1818
- cacheableInput: Math.ceil(words * profile.cacheableInputTokenPerWord),
1819
- input: Math.ceil(words * profile.inputTokenPerWord),
1820
- output: Math.ceil(words * profile.outputTokenPerWord)
1821
- }
2008
+ var import_wiki_graph_core5 = require("wiki-graph-core");
2009
+ async function inspectWikiGraphArchive(document, options) {
2010
+ const [allChapters, indexCacheCurrent, summaryWords, ...coverage] = await Promise.all([
2011
+ (0, import_wiki_graph_core5.listChapters)(document),
2012
+ (0, import_wiki_graph_core5.isArchiveSearchIndexCurrent)(document),
2013
+ readSummaryWords(document),
2014
+ document.indexArtifacts.listCoverage("fts"),
2015
+ document.indexArtifacts.listCoverage("embedding-source"),
2016
+ document.indexArtifacts.listCoverage("embedding-summary")
2017
+ ]);
2018
+ const chapters = selectChapters(allChapters, options.chapterId);
2019
+ const coverageByKind = {
2020
+ fts: byChapterId(coverage[0]),
2021
+ sourceEmbedding: byChapterId(coverage[1]),
2022
+ summaryEmbedding: byChapterId(coverage[2])
1822
2023
  };
1823
- }
1824
- function createGenerationPerformanceHints(input) {
1825
- if (!input.hasJobWork) {
1826
- return [];
1827
- }
1828
- const hints = [];
1829
- const recommendedRequest = input.concurrent.request < 4 ? DEFAULT_GENERATION_REQUEST_CONCURRENCY : input.concurrent.request < 8 ? 8 : void 0;
1830
- if (input.hasRequestWork && recommendedRequest !== void 0) {
1831
- hints.push({
1832
- configKey: "request",
1833
- configValue: recommendedRequest,
1834
- current: input.concurrent.request,
1835
- kind: "request",
1836
- message: "LLM request concurrency can often be higher. Use at least 4; 6-8 is usually faster when the provider allows it.",
1837
- recommended: recommendedRequest
1838
- });
1839
- }
1840
- if (input.concurrent.job < 4 && input.chapters > 1) {
1841
- hints.push({
1842
- configKey: "job",
1843
- configValue: 4,
1844
- current: input.concurrent.job,
1845
- kind: "job",
1846
- message: "Multiple chapters need work and job concurrency is below 4. Raising it lets chapter jobs run in parallel.",
1847
- recommended: 4
1848
- });
1849
- }
1850
- return hints;
1851
- }
1852
- function formatGenerationPlanningModel(llm) {
1853
- if (llm?.model === void 0) {
1854
- return "not configured";
1855
- }
1856
- return llm.provider === void 0 ? llm.model : `${llm.provider}/${llm.model}`;
1857
- }
1858
- function formatGenerationPlanningDuration(seconds) {
1859
- if (seconds < 60) {
1860
- return `${seconds}s`;
1861
- }
1862
- const minutes = Math.round(seconds / 60);
1863
- if (minutes < 60) {
1864
- return `${minutes}m`;
1865
- }
1866
- return `${Math.round(minutes / 60)}h`;
1867
- }
1868
- function getGenerationPlanningProfile(task) {
1869
- switch (task) {
1870
- case "index-fts":
1871
- return {
1872
- cacheableInputTokenPerWord: 0,
1873
- inputTokenPerWord: 0,
1874
- maxSecondsPerCall: 1,
1875
- minSecondsPerCall: 0,
1876
- outputTokenPerWord: 0,
1877
- secondsPerWord: 5e-4,
1878
- wordsPerCall: 1e5
1879
- };
1880
- case "index-embedding-source":
1881
- case "index-embedding-summary":
1882
- return {
1883
- cacheableInputTokenPerWord: 0,
1884
- inputTokenPerWord: 0,
1885
- maxSecondsPerCall: 10,
1886
- minSecondsPerCall: 1,
1887
- outputTokenPerWord: 0,
1888
- secondsPerWord: 2e-3,
1889
- wordsPerCall: 1e4
1890
- };
1891
- case "knowledge-graph":
1892
- return {
1893
- cacheableInputTokenPerWord: 60,
1894
- inputTokenPerWord: 80,
1895
- maxSecondsPerCall: 35,
1896
- minSecondsPerCall: 15,
1897
- outputTokenPerWord: 25,
1898
- secondsPerWord: 0.02,
1899
- wordsPerCall: 35
1900
- };
1901
- case "reading-graph":
1902
- return {
1903
- cacheableInputTokenPerWord: 20,
1904
- inputTokenPerWord: 25,
1905
- maxSecondsPerCall: 45,
1906
- minSecondsPerCall: 15,
1907
- outputTokenPerWord: 4,
1908
- secondsPerWord: 0.01,
1909
- wordsPerCall: 160
1910
- };
1911
- case "reading-summary":
2024
+ const inspections = await Promise.all(
2025
+ chapters.map(async (chapter) => {
2026
+ const serial = await document.serials.getById(chapter.chapterId);
1912
2027
  return {
1913
- cacheableInputTokenPerWord: 45,
1914
- inputTokenPerWord: 55,
1915
- maxSecondsPerCall: 25,
1916
- minSecondsPerCall: 10,
1917
- outputTokenPerWord: 4,
1918
- secondsPerWord: 0.01,
1919
- wordsPerCall: 110
2028
+ capabilities: {
2029
+ knowledgeGraph: {
2030
+ completed: serial?.knowledgeGraphReady === true
2031
+ },
2032
+ readingGraph: { completed: serial?.topologyReady === true },
2033
+ readingSummary: { completed: chapter.stage === "summarized" }
2034
+ },
2035
+ chapter,
2036
+ indexes: {
2037
+ fts: inspectArtifact(
2038
+ "fts",
2039
+ coverageByKind.fts.get(chapter.chapterId)
2040
+ ),
2041
+ sourceEmbedding: inspectArtifact(
2042
+ "embedding-source",
2043
+ coverageByKind.sourceEmbedding.get(chapter.chapterId)
2044
+ ),
2045
+ summaryEmbedding: inspectArtifact(
2046
+ "embedding-summary",
2047
+ coverageByKind.summaryEmbedding.get(chapter.chapterId)
2048
+ )
2049
+ },
2050
+ revision: serial?.revision ?? 0,
2051
+ summaryWords: summaryWords.get(chapter.chapterId) ?? 0
1920
2052
  };
1921
- }
1922
- }
1923
-
1924
- // src/archive/inspect.ts
1925
- async function createWikiGraphArchiveInspectReport(document, options) {
1926
- const { archiveUri } = options;
1927
- const [
1928
- chapters,
1929
- summaryWords,
1930
- indexCacheCurrent,
1931
- config,
1932
- ftsArtifactCoverage,
1933
- sourceEmbeddingArtifactCoverage,
1934
- summaryEmbeddingArtifactCoverage
1935
- ] = await Promise.all([
1936
- readInspectChapters(document, options.chapterId),
1937
- readSummaryWords(document, options.chapterId),
1938
- (0, import_wiki_graph_core4.isArchiveSearchIndexCurrent)(document),
1939
- loadWikiGraphRuntimeConfig(),
1940
- readIndexArtifactCoverage(document, "fts", options.chapterId),
1941
- readIndexArtifactCoverage(document, "embedding-source", options.chapterId),
1942
- readIndexArtifactCoverage(document, "embedding-summary", options.chapterId)
1943
- ]);
1944
- const selectedChapter = options.chapterId === void 0 ? void 0 : chapters[0];
1945
- const scopeUri = selectedChapter === void 0 ? archiveUri : formatInspectLocatedChapterUri(archiveUri, selectedChapter);
1946
- const concurrent = {
1947
- job: config.concurrent?.job ?? DEFAULT_GENERATION_JOB_CONCURRENCY,
1948
- request: config.concurrent?.request ?? DEFAULT_GENERATION_REQUEST_CONCURRENCY
1949
- };
1950
- const planningModel = formatGenerationPlanningModel(config.llm);
1951
- const contentChapters = chapters.filter(
1952
- (chapter) => chapter.stage !== "planned"
1953
- );
1954
- const sourceWords = sumWords(contentChapters);
1955
- const readingGraphCovered = contentChapters.filter(
1956
- (chapter) => chapter.readingGraphReady
1957
- );
1958
- const knowledgeGraphCovered = contentChapters.filter(
1959
- (chapter) => chapter.knowledgeGraphReady
1960
- );
1961
- const summaryCovered = contentChapters.filter(
1962
- (chapter) => chapter.summaryReady
1963
- );
1964
- const ftsArtifactCovered = filterChaptersByCurrentIndexArtifact(
1965
- contentChapters,
1966
- ftsArtifactCoverage
1967
- );
1968
- const sourceEmbeddingArtifactCovered = filterChaptersByCurrentIndexArtifact(
1969
- contentChapters,
1970
- sourceEmbeddingArtifactCoverage
1971
- );
1972
- const summaryEmbeddingArtifactCovered = filterChaptersByCurrentIndexArtifact(
1973
- contentChapters,
1974
- summaryEmbeddingArtifactCoverage
1975
- );
1976
- const queryBlockedContentChapters = contentChapters.filter(
1977
- (chapter) => !ftsArtifactCovered.includes(chapter) && !sourceEmbeddingArtifactCovered.includes(chapter)
1978
- );
1979
- const queryBlockedChapters = queryBlockedContentChapters.map(
1980
- (chapter) => createInspectChapterReference(archiveUri, chapter)
2053
+ })
1981
2054
  );
1982
- const queryReady = queryBlockedChapters.length === 0;
1983
- const improvements = createInspectImprovements({
1984
- concurrent,
1985
- contentChapters,
1986
- indexCacheCurrent,
1987
- planningModel,
1988
- queryBlockedChapters: queryBlockedContentChapters,
1989
- summaryCovered,
1990
- knowledgeGraphCovered,
1991
- readingGraphCovered
1992
- });
1993
- const performanceHints = createGenerationPerformanceHints({
1994
- chapters: Math.max(
1995
- 0,
1996
- ...improvements.map((improvement) => improvement.missingChapters ?? 0)
1997
- ),
1998
- concurrent,
1999
- hasJobWork: improvements.some(
2000
- (improvement) => improvement.planning !== void 0
2001
- ),
2002
- hasRequestWork: improvements.some(
2003
- (improvement) => improvement.planning !== void 0
2004
- )
2005
- });
2055
+ const selected = inspections[0];
2006
2056
  return {
2007
- archiveUri,
2008
- uri: scopeUri,
2057
+ archiveUri: options.archiveUri,
2058
+ chapters: inspections,
2059
+ localIndexCache: { current: indexCacheCurrent },
2009
2060
  scope: options.chapterId === void 0 ? { type: "archive" } : { chapterId: options.chapterId, type: "chapter" },
2010
- content: {
2011
- chapters: {
2012
- content: contentChapters.length,
2013
- planned: chapters.length - contentChapters.length,
2014
- total: chapters.length
2015
- },
2016
- sourceWords,
2017
- summaryWords
2018
- },
2019
- localIndexCache: {
2020
- current: indexCacheCurrent,
2021
- ...!queryReady ? {
2022
- blockedBy: "missing-search-artifacts",
2023
- impact: "The cache cannot be built until every content chapter has a current FTS or source embedding artifact."
2024
- } : indexCacheCurrent ? {} : {
2025
- impact: "The next archive query may need to sync index cache first.",
2026
- resource: "local CPU/disk time only; no provider calls."
2027
- },
2028
- status: !queryReady ? "blocked" : indexCacheCurrent ? "current" : "missing-or-outdated",
2029
- syncAvailable: queryReady && !indexCacheCurrent
2030
- },
2031
- coverage: {
2032
- ftsIndexArtifact: createInspectCoverage(
2033
- ftsArtifactCovered,
2034
- contentChapters
2035
- ),
2036
- knowledgeGraph: createInspectCoverage(
2037
- knowledgeGraphCovered,
2038
- contentChapters
2039
- ),
2040
- readingGraph: createInspectCoverage(readingGraphCovered, contentChapters),
2041
- summary: createInspectCoverage(summaryCovered, contentChapters),
2042
- sourceEmbeddingIndexArtifact: createInspectCoverage(
2043
- sourceEmbeddingArtifactCovered,
2044
- contentChapters
2045
- ),
2046
- summaryEmbeddingIndexArtifact: createInspectCoverage(
2047
- summaryEmbeddingArtifactCovered,
2048
- contentChapters
2049
- )
2050
- },
2051
- query: {
2052
- ready: queryReady
2053
- },
2054
- searchArtifacts: {
2055
- blockedChapters: queryBlockedChapters,
2056
- ...!queryReady ? {
2057
- resource: "local CPU/disk time only; no provider calls."
2058
- } : {},
2059
- ready: queryReady,
2060
- status: queryReady ? "ready" : "incomplete"
2061
- },
2062
- retrievalGuidance: formatRetrievalGuidance({
2063
- indexCacheCurrent,
2064
- knowledgeGraphCovered,
2065
- readingGraphCovered,
2066
- contentChapters,
2067
- queryReady,
2068
- sourceWords
2069
- }),
2070
- improvements,
2071
- performanceHints,
2072
- summaryCoverageNote: "Summary coverage means a current summary artifact exists for the chapter; it does not guarantee that every source topic is represented in the summary text."
2073
- };
2074
- }
2075
- function createInspectChapterReference(archiveUri, chapter) {
2076
- return {
2077
- chapterId: chapter.chapterId,
2078
- locatedUri: formatInspectLocatedChapterUri(archiveUri, chapter),
2079
- title: chapter.title,
2080
- uri: chapter.uri
2061
+ uri: selected === void 0 || options.chapterId === void 0 ? options.archiveUri : formatLocatedChapterUri(options.archiveUri, selected.chapter)
2081
2062
  };
2082
2063
  }
2083
- function formatInspectLocatedChapterUri(archiveUri, chapter) {
2084
- return `${archiveUri.replace(/\/+$/u, "")}/${chapter.uri.replace(/^wikg:\/\//u, "")}`;
2085
- }
2086
- async function readInspectChapters(document, chapterId) {
2087
- const chapters = chapterId === void 0 ? await (0, import_wiki_graph_core4.listChapters)(document) : (await (0, import_wiki_graph_core4.listChapters)(document)).filter(
2064
+ function selectChapters(chapters, chapterId) {
2065
+ if (chapterId === void 0) return chapters;
2066
+ const selected = chapters.filter(
2088
2067
  (chapter) => chapter.chapterId === chapterId
2089
2068
  );
2090
- if (chapterId !== void 0 && chapters.length === 0) {
2069
+ if (selected.length === 0) {
2091
2070
  throw new Error(`Chapter ${chapterId} does not exist.`);
2092
2071
  }
2093
- return await Promise.all(
2094
- chapters.map(async (chapter) => {
2095
- const serial = await document.serials.getById(chapter.chapterId);
2096
- return {
2097
- ...chapter,
2098
- knowledgeGraphReady: serial?.knowledgeGraphReady === true,
2099
- readingGraphReady: serial?.topologyReady === true,
2100
- summaryReady: chapter.stage === "summarized"
2101
- };
2102
- })
2103
- );
2072
+ return selected;
2104
2073
  }
2105
- async function readSummaryWords(document, chapterId) {
2106
- return await document.readDatabase(
2107
- async (database) => await database.queryOne(
2108
- `
2109
- SELECT COALESCE(SUM(words_count), 0) AS words
2110
- FROM text_sentence_records
2111
- WHERE kind = 2
2112
- ${chapterId === void 0 ? "" : "AND chapter_id = ?"}
2113
- `,
2114
- chapterId === void 0 ? void 0 : [chapterId],
2115
- (row) => Number(row.words)
2116
- ) ?? 0
2117
- );
2074
+ function byChapterId(coverage) {
2075
+ return new Map(coverage.map((item) => [item.serialId, item]));
2118
2076
  }
2119
- async function readIndexArtifactCoverage(document, kind, chapterId) {
2120
- const coverage = await document.indexArtifacts.listCoverage(kind);
2121
- return chapterId === void 0 ? coverage : coverage.filter((item) => item.serialId === chapterId);
2122
- }
2123
- function filterChaptersByCurrentIndexArtifact(chapters, coverage) {
2124
- const currentChapterIds = new Set(
2125
- coverage.filter((item) => item.current).map((item) => item.serialId)
2126
- );
2127
- return chapters.filter((chapter) => currentChapterIds.has(chapter.chapterId));
2128
- }
2129
- function createInspectCoverage(covered, total) {
2130
- const coveredWords = sumWords(covered);
2131
- const totalWords = sumWords(total);
2077
+ function inspectArtifact(kind, coverage) {
2132
2078
  return {
2133
- coveredChapters: covered.length,
2134
- coveredWords,
2135
- percent: formatPercent(coveredWords, totalWords),
2136
- totalChapters: total.length,
2137
- totalWords
2079
+ current: coverage?.current === true,
2080
+ exists: coverage?.sourceRevision !== void 0,
2081
+ kind,
2082
+ ...coverage?.sourceRevision === void 0 ? {} : { sourceRevision: coverage.sourceRevision }
2138
2083
  };
2139
2084
  }
2140
- function formatRetrievalGuidance(input) {
2141
- if (input.sourceWords === 0 || input.contentChapters.length === 0) {
2142
- return [
2143
- "Source content: empty.",
2144
- "Add source text before using query coverage or graph-based retrieval."
2145
- ];
2146
- }
2147
- const lines = [
2148
- input.queryReady ? `Query: available; local index cache is ${input.indexCacheCurrent ? "current" : "missing or outdated and can be synced from artifacts"}.` : "Query: unavailable until every content chapter has a current FTS or source embedding artifact."
2149
- ];
2150
- lines.push(
2151
- formatObjectSearchGuidance(
2152
- "Reading Graph object retrieval",
2153
- input.readingGraphCovered,
2154
- input.contentChapters
2155
- )
2156
- );
2157
- lines.push(
2158
- formatObjectSearchGuidance(
2159
- "Entity/triple retrieval",
2160
- input.knowledgeGraphCovered,
2161
- input.contentChapters
2085
+ async function readSummaryWords(document) {
2086
+ const rows = await document.readDatabase(
2087
+ async (database) => await database.queryAll(
2088
+ `
2089
+ SELECT chapter_id, COALESCE(SUM(words_count), 0) AS words
2090
+ FROM text_sentence_records
2091
+ WHERE kind = 2
2092
+ GROUP BY chapter_id
2093
+ `,
2094
+ void 0,
2095
+ (row) => ({
2096
+ chapterId: Number(row.chapter_id),
2097
+ words: Number(row.words)
2098
+ })
2162
2099
  )
2163
2100
  );
2164
- return lines;
2165
- }
2166
- function formatObjectSearchGuidance(label, covered, total) {
2167
- const coveredWords = sumWords(covered);
2168
- const totalWords = sumWords(total);
2169
- const ratio = totalWords === 0 ? 0 : coveredWords / totalWords;
2170
- const coverage = formatPercent(coveredWords, totalWords);
2171
- if (ratio >= 1) {
2172
- return `${label}: covers all source content; it can represent the full scope for object retrieval.`;
2173
- }
2174
- if (ratio >= 0.9) {
2175
- return `${label}: covers ${coverage}; use it as the main path, but source --query is needed for uncovered content.`;
2176
- }
2177
- if (ratio >= 0.5) {
2178
- return `${label}: covers ${coverage}; use it as leads, not as a full-scope substitute for source --query.`;
2179
- }
2180
- return `${label}: covers ${coverage}; build missing graph coverage before relying on object retrieval.`;
2181
- }
2182
- function createInspectImprovements(input) {
2183
- const improvements = [];
2184
- if (input.contentChapters.length === 0) {
2185
- improvements.push({
2186
- kind: "add-source",
2187
- recommendation: "No source content is available yet; add or import source text before graph or summary generation.",
2188
- title: "Add source content"
2189
- });
2190
- return improvements;
2191
- }
2192
- if (input.queryBlockedChapters.length > 0) {
2193
- improvements.push({
2194
- kind: "build",
2195
- missingChapters: input.queryBlockedChapters.length,
2196
- missingWords: sumWords(input.queryBlockedChapters),
2197
- recommendation: "Build local FTS artifacts to make this scope queryable. This does not call a provider.",
2198
- task: "index-fts",
2199
- title: "Enable query with local FTS"
2200
- });
2201
- } else if (!input.indexCacheCurrent) {
2202
- improvements.push({
2203
- kind: "sync-index",
2204
- recommendation: "Sync the index cache from chapter index artifacts so query starts without a lazy cache rebuild.",
2205
- title: "Sync index cache"
2206
- });
2207
- }
2208
- improvements.push(
2209
- ...createGraphImprovement({
2210
- concurrent: input.concurrent,
2211
- covered: input.readingGraphCovered,
2212
- planningModel: input.planningModel,
2213
- task: "reading-graph",
2214
- title: "Complete Reading Graph coverage",
2215
- total: input.contentChapters
2216
- })
2217
- );
2218
- improvements.push(
2219
- ...createGraphImprovement({
2220
- concurrent: input.concurrent,
2221
- covered: input.knowledgeGraphCovered,
2222
- planningModel: input.planningModel,
2223
- task: "knowledge-graph",
2224
- title: "Complete Knowledge Graph coverage",
2225
- total: input.contentChapters
2226
- })
2227
- );
2228
- improvements.push(
2229
- ...createGraphImprovement({
2230
- concurrent: input.concurrent,
2231
- covered: input.summaryCovered,
2232
- planningModel: input.planningModel,
2233
- task: "reading-summary",
2234
- title: "Complete Summary coverage",
2235
- total: input.contentChapters
2236
- })
2237
- );
2238
- return improvements;
2101
+ return new Map(rows.map((row) => [row.chapterId, row.words]));
2239
2102
  }
2240
- function createGraphImprovement(input) {
2241
- const coveredIds = new Set(input.covered.map((chapter) => chapter.chapterId));
2242
- const missing = input.total.filter(
2243
- (chapter) => !coveredIds.has(chapter.chapterId)
2244
- );
2245
- if (missing.length === 0) {
2246
- return [];
2247
- }
2248
- const missingWords = sumWords(missing);
2249
- return [
2250
- {
2251
- kind: "build",
2252
- missingChapters: missing.length,
2253
- missingWords,
2254
- planning: planGenerationTask(
2255
- input.task,
2256
- missingWords,
2257
- missing.length,
2258
- input.concurrent,
2259
- input.planningModel
2260
- ),
2261
- recommendation: formatImprovementRecommendation(
2262
- input.covered,
2263
- input.total,
2264
- missingWords
2265
- ),
2266
- task: input.task,
2267
- title: input.title
2268
- }
2269
- ];
2270
- }
2271
- function formatImprovementRecommendation(covered, total, missingWords) {
2272
- const totalWords = sumWords(total);
2273
- const coveredWords = sumWords(covered);
2274
- if (totalWords === 0) {
2275
- return "No source content is available.";
2276
- }
2277
- if (total.length === 1 || coveredWords / totalWords >= 0.9 || missingWords <= 1e3) {
2278
- return "Queue the full scope to finish the remaining gap.";
2279
- }
2280
- return "Queue selected chapters first if only part of the scope matters.";
2281
- }
2282
- function sumWords(chapters) {
2283
- return chapters.reduce((total, chapter) => total + chapter.words, 0);
2103
+ function formatLocatedChapterUri(archiveUri, chapter) {
2104
+ return `${archiveUri.replace(/\/+$/u, "")}/${chapter.uri.replace(/^wikg:\/\//u, "")}`;
2284
2105
  }
2285
- function formatPercent(numerator, denominator) {
2286
- if (denominator === 0) {
2287
- return "n/a";
2106
+
2107
+ // src/archive/write.ts
2108
+ var import_wiki_graph_core6 = require("wiki-graph-core");
2109
+ async function writeWikiGraphArchiveLocation(location, operation, options = {}) {
2110
+ const cacheOnly = options.searchIndexWritebackPolicy === "cache";
2111
+ const write = async (archiveFile = location.archiveFile) => await new import_wiki_graph_core6.WikiGraphArchiveFile(archiveFile).write(operation, {
2112
+ ...cacheOnly ? {} : { derivedStateKeys: [location.archiveKey, location.archivePath] },
2113
+ ...options.invalidateContinuationCursors === void 0 ? {} : {
2114
+ invalidateContinuationCursors: options.invalidateContinuationCursors
2115
+ },
2116
+ ...options.searchIndexWritebackPolicy === void 0 ? {} : { searchIndexWritebackPolicy: options.searchIndexWritebackPolicy }
2117
+ });
2118
+ if (location.libraryArchiveTarget === void 0 || cacheOnly || options.refreshLibraryIndex === false) {
2119
+ return await write();
2288
2120
  }
2289
- const percent = numerator / denominator * 100;
2290
- return `${Number.isInteger(percent) ? percent.toFixed(0) : percent.toFixed(1)}%`;
2121
+ return await (0, import_wiki_graph_core6.writeWikiGraphLibraryArchive)({
2122
+ additionalDerivedStateKeys: [location.archiveKey, location.archivePath],
2123
+ ...options.invalidateContinuationCursors === void 0 ? {} : {
2124
+ invalidateContinuationCursors: options.invalidateContinuationCursors
2125
+ },
2126
+ ...options.onIndexSyncError === void 0 ? {} : { onIndexSyncError: options.onIndexSyncError },
2127
+ operation: async (archiveFile) => await write(archiveFile),
2128
+ target: location.libraryArchiveTarget
2129
+ });
2291
2130
  }
2292
2131
 
2293
2132
  // src/archive/archive.ts
@@ -2307,13 +2146,13 @@ var WikiGraphArchiveManager = class {
2307
2146
  }
2308
2147
  async create(options) {
2309
2148
  return await this.#runtime.run(async () => {
2310
- const path = resolveWikiGraphRuntimePath(options.path);
2149
+ const path = await assertStandaloneWikiGraphArchivePath(options.path);
2311
2150
  if (options.replace !== true && await nodePathExists(path)) {
2312
2151
  throw new WikiGraphArchiveExistsError(path);
2313
2152
  }
2314
- const outputPath = (0, import_path4.join)(
2315
- (0, import_path4.dirname)(path),
2316
- `.${(0, import_path4.basename)(path)}.${(0, import_crypto2.randomUUID)()}.tmp.wikg`
2153
+ const outputPath = (0, import_path5.join)(
2154
+ (0, import_path5.dirname)(path),
2155
+ `.${(0, import_path5.basename)(path)}.${(0, import_crypto2.randomUUID)()}.tmp.wikg`
2317
2156
  );
2318
2157
  try {
2319
2158
  if (options.importPath === void 0) {
@@ -2327,10 +2166,10 @@ var WikiGraphArchiveManager = class {
2327
2166
  });
2328
2167
  }
2329
2168
  if (options.replace === true) {
2330
- await (0, import_promises3.rename)(outputPath, path);
2169
+ await (0, import_promises4.rename)(outputPath, path);
2331
2170
  } else {
2332
2171
  try {
2333
- await (0, import_promises3.link)(outputPath, path);
2172
+ await (0, import_promises4.link)(outputPath, path);
2334
2173
  } catch (error) {
2335
2174
  if (isNodeEEXISTError(error)) {
2336
2175
  throw new WikiGraphArchiveExistsError(path);
@@ -2338,15 +2177,15 @@ var WikiGraphArchiveManager = class {
2338
2177
  throw error;
2339
2178
  }
2340
2179
  }
2341
- return { locatedUri: (0, import_wiki_graph_core5.formatLocatedWikiGraphUri)(path), path };
2180
+ return { locatedUri: (0, import_wiki_graph_core7.formatLocatedWikiGraphUri)(path), path };
2342
2181
  } finally {
2343
- await (0, import_promises3.rm)(outputPath, { force: true, recursive: true });
2182
+ await (0, import_promises4.rm)(outputPath, { force: true, recursive: true });
2344
2183
  }
2345
2184
  }, options.signal);
2346
2185
  }
2347
- async open(uriOrPath, options = {}) {
2186
+ async open(target, options = {}) {
2348
2187
  const location = await this.#runtime.run(
2349
- async () => await resolveWikiGraphArchiveLocation(uriOrPath),
2188
+ async () => await resolveWikiGraphArchiveLocation(target),
2350
2189
  options.signal
2351
2190
  );
2352
2191
  return new WikiGraphArchiveHandle(this.#runtime, location);
@@ -2369,14 +2208,17 @@ var WikiGraphArchiveHandle = class {
2369
2208
  return this.#location.locatedUri;
2370
2209
  }
2371
2210
  get objectUri() {
2372
- return (0, import_wiki_graph_core5.parseLocatedWikiGraphUri)(this.#location.locatedUri).objectUri ?? "wikg://";
2211
+ return (0, import_wiki_graph_core7.parseLocatedWikiGraphUri)(this.#location.locatedUri).objectUri ?? "wikg://";
2373
2212
  }
2374
2213
  get path() {
2375
2214
  return this.#location.archivePath;
2376
2215
  }
2216
+ get target() {
2217
+ return this.#location.target;
2218
+ }
2377
2219
  async inspect(options = {}) {
2378
2220
  return await this.#readDocument(
2379
- async (document) => await createWikiGraphArchiveInspectReport(document, {
2221
+ async (document) => await inspectWikiGraphArchive(document, {
2380
2222
  archiveUri: this.#location.publicArchiveUri ?? this.locatedUri,
2381
2223
  ...options.chapterId === void 0 ? {} : { chapterId: options.chapterId }
2382
2224
  }),
@@ -2395,7 +2237,7 @@ var WikiGraphArchiveHandle = class {
2395
2237
  ...chapters === void 0 ? {} : { chapters },
2396
2238
  ...embeddingProvider === void 0 ? {} : { embeddingProvider }
2397
2239
  });
2398
- return await (0, import_wiki_graph_core5.findArchiveObjects)(document, query, {
2240
+ return await (0, import_wiki_graph_core7.findArchiveObjects)(document, query, {
2399
2241
  ...withoutOperationAndScope(options),
2400
2242
  archiveKey: this.archiveKey,
2401
2243
  ...chapters === void 0 ? {} : { chapters },
@@ -2410,14 +2252,14 @@ var WikiGraphArchiveHandle = class {
2410
2252
  }
2411
2253
  async list(options = {}) {
2412
2254
  return await this.#readDocument(async (document) => {
2413
- if ((0, import_wiki_graph_core5.isSourceLocatorScopeUri)(this.objectUri)) {
2414
- return await (0, import_wiki_graph_core5.listArchiveSourceLocators)(document, this.objectUri, {
2255
+ if ((0, import_wiki_graph_core7.isSourceLocatorScopeUri)(this.objectUri)) {
2256
+ return await (0, import_wiki_graph_core7.listArchiveSourceLocators)(document, this.objectUri, {
2415
2257
  ...options.cursor === void 0 ? {} : { cursor: options.cursor },
2416
2258
  ...options.limit === void 0 ? {} : { limit: options.limit }
2417
2259
  });
2418
2260
  }
2419
2261
  const chapters = await this.#resolveScope(document, options);
2420
- return await (0, import_wiki_graph_core5.listArchiveCollection)(document, {
2262
+ return await (0, import_wiki_graph_core7.listArchiveCollection)(document, {
2421
2263
  ...withoutOperationAndScope(options),
2422
2264
  ...chapters === void 0 ? {} : { chapters }
2423
2265
  });
@@ -2445,8 +2287,8 @@ var WikiGraphArchiveHandle = class {
2445
2287
  async getSearchIndexStatus(options = {}) {
2446
2288
  return await this.#readDocument(
2447
2289
  async (document) => ({
2448
- capabilities: await (0, import_wiki_graph_core5.readSearchIndexCapabilityStatus)(document),
2449
- current: await (0, import_wiki_graph_core5.isArchiveSearchIndexCurrent)(document)
2290
+ capabilities: await (0, import_wiki_graph_core7.readSearchIndexCapabilityStatus)(document),
2291
+ current: await (0, import_wiki_graph_core7.isArchiveSearchIndexCurrent)(document)
2450
2292
  }),
2451
2293
  options
2452
2294
  );
@@ -2454,14 +2296,14 @@ var WikiGraphArchiveHandle = class {
2454
2296
  async syncSearchIndex(options = {}) {
2455
2297
  const rebuilt = await this.#writeDocument(
2456
2298
  async (document) => {
2457
- const scope = options.skipUnindexed === true ? { chapters: await (0, import_wiki_graph_core5.listArchiveQueryableChapterIds)(document) } : {};
2299
+ const scope = options.skipUnindexed === true ? { chapters: await (0, import_wiki_graph_core7.listArchiveQueryableChapterIds)(document) } : {};
2458
2300
  if (scope.chapters?.length === 0) {
2459
2301
  throw new Error(
2460
2302
  "Wiki Graph index cache is not ready. No chapters have a current FTS artifact or source embedding artifact."
2461
2303
  );
2462
2304
  }
2463
- if (await (0, import_wiki_graph_core5.isArchiveSearchIndexCurrent)(document, scope)) return false;
2464
- await (0, import_wiki_graph_core5.rebuildArchiveSearchIndex)(document, options.onProgress, scope);
2305
+ if (await (0, import_wiki_graph_core7.isArchiveSearchIndexCurrent)(document, scope)) return false;
2306
+ await (0, import_wiki_graph_core7.rebuildArchiveSearchIndex)(document, options.onProgress, scope);
2465
2307
  return true;
2466
2308
  },
2467
2309
  {
@@ -2470,7 +2312,7 @@ var WikiGraphArchiveHandle = class {
2470
2312
  }
2471
2313
  );
2472
2314
  await this.#runtime.run(
2473
- async () => await (0, import_wiki_graph_core5.deleteArchiveSearchSessions)(this.path),
2315
+ async () => await (0, import_wiki_graph_core7.deleteArchiveSearchSessions)(this.path),
2474
2316
  options.signal
2475
2317
  );
2476
2318
  return { rebuilt };
@@ -2493,21 +2335,21 @@ var WikiGraphArchiveHandle = class {
2493
2335
  }
2494
2336
  );
2495
2337
  await this.#runtime.run(
2496
- async () => await (0, import_wiki_graph_core5.deleteArchiveSearchSessions)(this.path),
2338
+ async () => await (0, import_wiki_graph_core7.deleteArchiveSearchSessions)(this.path),
2497
2339
  options.signal
2498
2340
  );
2499
2341
  return status;
2500
2342
  }
2501
2343
  async listChapters(options = {}) {
2502
2344
  return await this.#readDocument(
2503
- async (document) => await (0, import_wiki_graph_core5.listChapters)(document),
2345
+ async (document) => await (0, import_wiki_graph_core7.listChapters)(document),
2504
2346
  options
2505
2347
  );
2506
2348
  }
2507
2349
  async getChapter(path, options = {}) {
2508
2350
  return await this.#readDocument(async (document) => {
2509
- const chapterId = await (0, import_wiki_graph_core5.resolveChapterPathReadonly)(document, path);
2510
- return requireChapter(await (0, import_wiki_graph_core5.listChapters)(document), chapterId);
2351
+ const chapterId = await (0, import_wiki_graph_core7.resolveChapterPathReadonly)(document, path);
2352
+ return requireChapter(await (0, import_wiki_graph_core7.listChapters)(document), chapterId);
2511
2353
  }, options);
2512
2354
  }
2513
2355
  async addChapter(options) {
@@ -2516,17 +2358,17 @@ var WikiGraphArchiveHandle = class {
2516
2358
  document,
2517
2359
  options.parentPath
2518
2360
  );
2519
- await (0, import_wiki_graph_core5.assertNoActiveBuildJobConflicts)({
2361
+ await (0, import_wiki_graph_core7.assertNoActiveBuildJobConflicts)({
2520
2362
  archive: this.#location.archiveFile,
2521
2363
  operation: "Adding chapter",
2522
2364
  scope: { kind: "archive" }
2523
2365
  });
2524
- let details = await (0, import_wiki_graph_core5.addChapter)(document, {
2366
+ let details = await (0, import_wiki_graph_core7.addChapter)(document, {
2525
2367
  ...parentChapterId === void 0 ? {} : { parentChapterId },
2526
2368
  ...options.title === void 0 ? {} : { title: options.title }
2527
2369
  });
2528
2370
  if (options.source !== void 0) {
2529
- details = await (0, import_wiki_graph_core5.setChapterSource)(
2371
+ details = await (0, import_wiki_graph_core7.setChapterSource)(
2530
2372
  document,
2531
2373
  details.chapterId,
2532
2374
  asTextStream(options.source)
@@ -2537,7 +2379,7 @@ var WikiGraphArchiveHandle = class {
2537
2379
  }
2538
2380
  async getChapterArtifact(path, kind) {
2539
2381
  return await this.#readDocument(async (document) => {
2540
- const chapterId = await (0, import_wiki_graph_core5.resolveChapterPathReadonly)(document, path);
2382
+ const chapterId = await (0, import_wiki_graph_core7.resolveChapterPathReadonly)(document, path);
2541
2383
  const [artifact, revision] = await Promise.all([
2542
2384
  document.indexArtifacts.get(chapterId, kind),
2543
2385
  document.serials.getRevision(chapterId)
@@ -2560,25 +2402,25 @@ var WikiGraphArchiveHandle = class {
2560
2402
  }
2561
2403
  async deleteChapterArtifact(path, kind) {
2562
2404
  return await this.#writeDocument(async (document) => {
2563
- const chapterId = await (0, import_wiki_graph_core5.resolveChapterPathReadonly)(document, path);
2405
+ const chapterId = await (0, import_wiki_graph_core7.resolveChapterPathReadonly)(document, path);
2564
2406
  await document.indexArtifacts.delete(chapterId, kind);
2565
2407
  return { chapterId, deleted: true, kind };
2566
2408
  });
2567
2409
  }
2568
2410
  async moveChapter(path, options) {
2569
2411
  return await this.#writeDocument(async (document) => {
2570
- const chapterId = await (0, import_wiki_graph_core5.resolveChapterPathReadonly)(document, path);
2412
+ const chapterId = await (0, import_wiki_graph_core7.resolveChapterPathReadonly)(document, path);
2571
2413
  const [afterChapterId, beforeChapterId, parentChapterId] = await Promise.all([
2572
2414
  resolveOptionalChapterPath(document, options.afterPath),
2573
2415
  resolveOptionalChapterPath(document, options.beforePath),
2574
2416
  resolveOptionalChapterPath(document, options.parentPath)
2575
2417
  ]);
2576
- await (0, import_wiki_graph_core5.assertNoActiveBuildJobConflicts)({
2418
+ await (0, import_wiki_graph_core7.assertNoActiveBuildJobConflicts)({
2577
2419
  archive: this.#location.archiveFile,
2578
2420
  operation: "Moving chapter",
2579
2421
  scope: { kind: "archive" }
2580
2422
  });
2581
- return await (0, import_wiki_graph_core5.moveChapter)(document, chapterId, {
2423
+ return await (0, import_wiki_graph_core7.moveChapter)(document, chapterId, {
2582
2424
  ...afterChapterId === void 0 ? {} : { afterChapterId },
2583
2425
  ...beforeChapterId === void 0 ? {} : { beforeChapterId },
2584
2426
  ...parentChapterId === void 0 ? {} : { parentChapterId },
@@ -2590,35 +2432,35 @@ var WikiGraphArchiveHandle = class {
2590
2432
  }
2591
2433
  async removeChapter(path, recursive = false) {
2592
2434
  await this.#writeDocument(async (document) => {
2593
- const chapterId = await (0, import_wiki_graph_core5.resolveChapterPathReadonly)(document, path);
2594
- await (0, import_wiki_graph_core5.assertNoActiveBuildJobConflicts)({
2435
+ const chapterId = await (0, import_wiki_graph_core7.resolveChapterPathReadonly)(document, path);
2436
+ await (0, import_wiki_graph_core7.assertNoActiveBuildJobConflicts)({
2595
2437
  archive: this.#location.archiveFile,
2596
2438
  operation: "Removing chapter",
2597
2439
  scope: { kind: "archive" }
2598
2440
  });
2599
- await (0, import_wiki_graph_core5.removeChapter)(document, chapterId, { recursive });
2441
+ await (0, import_wiki_graph_core7.removeChapter)(document, chapterId, { recursive });
2600
2442
  });
2601
2443
  }
2602
2444
  async resetChapter(path, stage) {
2603
2445
  return await this.#writeDocument(async (document) => {
2604
- const chapterId = await (0, import_wiki_graph_core5.resolveChapterPathReadonly)(document, path);
2446
+ const chapterId = await (0, import_wiki_graph_core7.resolveChapterPathReadonly)(document, path);
2605
2447
  await assertChapterResetAllowed(
2606
2448
  this.#location.archiveFile,
2607
2449
  chapterId,
2608
2450
  stage
2609
2451
  );
2610
- return await (0, import_wiki_graph_core5.resetChapter)(document, chapterId, stage);
2452
+ return await (0, import_wiki_graph_core7.resetChapter)(document, chapterId, stage);
2611
2453
  });
2612
2454
  }
2613
2455
  async setChapterSource(path, source, options = {}) {
2614
2456
  return await this.#writeDocument(async (document) => {
2615
- const chapterId = await (0, import_wiki_graph_core5.resolveChapterPathReadonly)(document, path);
2616
- await (0, import_wiki_graph_core5.assertNoActiveBuildJobs)({
2457
+ const chapterId = await (0, import_wiki_graph_core7.resolveChapterPathReadonly)(document, path);
2458
+ await (0, import_wiki_graph_core7.assertNoActiveBuildJobs)({
2617
2459
  archive: this.#location.archiveFile,
2618
2460
  chapterIds: [chapterId],
2619
2461
  operation: "Setting chapter source"
2620
2462
  });
2621
- return await (0, import_wiki_graph_core5.setChapterSource)(
2463
+ return await (0, import_wiki_graph_core7.setChapterSource)(
2622
2464
  document,
2623
2465
  chapterId,
2624
2466
  asTextStream(source),
@@ -2628,43 +2470,43 @@ var WikiGraphArchiveHandle = class {
2628
2470
  }
2629
2471
  async setChapterSummary(path, summary) {
2630
2472
  return await this.#writeDocument(async (document) => {
2631
- const chapterId = await (0, import_wiki_graph_core5.resolveChapterPathReadonly)(document, path);
2632
- await (0, import_wiki_graph_core5.assertNoActiveBuildJobs)({
2473
+ const chapterId = await (0, import_wiki_graph_core7.resolveChapterPathReadonly)(document, path);
2474
+ await (0, import_wiki_graph_core7.assertNoActiveBuildJobs)({
2633
2475
  archive: this.#location.archiveFile,
2634
2476
  chapterIds: [chapterId],
2635
2477
  operation: "Setting chapter summary",
2636
2478
  requiresTarget: "reading-summary"
2637
2479
  });
2638
- return await (0, import_wiki_graph_core5.setChapterSummary)(document, chapterId, summary);
2480
+ return await (0, import_wiki_graph_core7.setChapterSummary)(document, chapterId, summary);
2639
2481
  });
2640
2482
  }
2641
2483
  async setChapterTitle(path, title) {
2642
2484
  return await this.#writeDocument(async (document) => {
2643
- const chapterId = await (0, import_wiki_graph_core5.resolveChapterPathReadonly)(document, path);
2644
- await (0, import_wiki_graph_core5.assertNoActiveBuildJobs)({
2485
+ const chapterId = await (0, import_wiki_graph_core7.resolveChapterPathReadonly)(document, path);
2486
+ await (0, import_wiki_graph_core7.assertNoActiveBuildJobs)({
2645
2487
  archive: this.#location.archiveFile,
2646
2488
  chapterIds: [chapterId],
2647
2489
  operation: "Setting chapter title"
2648
2490
  });
2649
- return await (0, import_wiki_graph_core5.setChapterTitle)(document, chapterId, title);
2491
+ return await (0, import_wiki_graph_core7.setChapterTitle)(document, chapterId, title);
2650
2492
  });
2651
2493
  }
2652
2494
  async getChapterTree() {
2653
2495
  return await this.#readDocument(
2654
- async (document) => await (0, import_wiki_graph_core5.getChapterTree)(document)
2496
+ async (document) => await (0, import_wiki_graph_core7.getChapterTree)(document)
2655
2497
  );
2656
2498
  }
2657
2499
  async applyChapterTree(tree, options = {}) {
2658
2500
  return await this.#writeDocument(
2659
2501
  async (document) => {
2660
2502
  if (options.dryRun !== true) {
2661
- await (0, import_wiki_graph_core5.assertNoActiveBuildJobConflicts)({
2503
+ await (0, import_wiki_graph_core7.assertNoActiveBuildJobConflicts)({
2662
2504
  archive: this.#location.archiveFile,
2663
2505
  operation: "Changing chapter tree",
2664
2506
  scope: { kind: "archive" }
2665
2507
  });
2666
2508
  }
2667
- return await (0, import_wiki_graph_core5.applyChapterTree)(document, tree, {
2509
+ return await (0, import_wiki_graph_core7.applyChapterTree)(document, tree, {
2668
2510
  dryRun: options.dryRun ?? false
2669
2511
  });
2670
2512
  },
@@ -2676,8 +2518,8 @@ var WikiGraphArchiveHandle = class {
2676
2518
  async () => await withConfiguredWikimediaResolver(
2677
2519
  objectUri,
2678
2520
  async (wikimediaOptions) => await this.#readDocument(
2679
- async (document) => await (0, import_wiki_graph_core5.readArchivePage)(document, objectUri, {
2680
- ...withoutOperation(options),
2521
+ async (document) => await (0, import_wiki_graph_core7.readArchivePage)(document, objectUri, {
2522
+ ...options,
2681
2523
  ...wikimediaOptions
2682
2524
  }),
2683
2525
  options
@@ -2690,7 +2532,7 @@ var WikiGraphArchiveHandle = class {
2690
2532
  if (options.query === void 0) {
2691
2533
  return await this.#readDocument(async (document) => {
2692
2534
  const chapters = await this.#resolveScope(document, {});
2693
- return await (0, import_wiki_graph_core5.listRelatedArchiveObjects)(document, objectUri, {
2535
+ return await (0, import_wiki_graph_core7.listRelatedArchiveObjects)(document, objectUri, {
2694
2536
  ...withoutOperation(options),
2695
2537
  ...chapters === void 0 ? {} : { chapters }
2696
2538
  });
@@ -2707,7 +2549,7 @@ var WikiGraphArchiveHandle = class {
2707
2549
  ...chapters === void 0 ? {} : { chapters },
2708
2550
  ...embeddingProvider === void 0 ? {} : { embeddingProvider }
2709
2551
  });
2710
- return await (0, import_wiki_graph_core5.listRelatedArchiveObjects)(document, objectUri, {
2552
+ return await (0, import_wiki_graph_core7.listRelatedArchiveObjects)(document, objectUri, {
2711
2553
  ...withoutOperation(options),
2712
2554
  ...chapters === void 0 ? {} : { chapters }
2713
2555
  });
@@ -2722,7 +2564,7 @@ var WikiGraphArchiveHandle = class {
2722
2564
  if (options.query === void 0) {
2723
2565
  return await this.#readDocument(async (document) => {
2724
2566
  const chapters = await this.#resolveScope(document, {});
2725
- return await (0, import_wiki_graph_core5.listArchiveEvidence)(document, objectUri, {
2567
+ return await (0, import_wiki_graph_core7.listArchiveEvidence)(document, objectUri, {
2726
2568
  ...withoutOperation(options),
2727
2569
  ...chapters === void 0 ? {} : { chapters }
2728
2570
  });
@@ -2739,7 +2581,7 @@ var WikiGraphArchiveHandle = class {
2739
2581
  ...chapters === void 0 ? {} : { chapters },
2740
2582
  ...embeddingProvider === void 0 ? {} : { embeddingProvider }
2741
2583
  });
2742
- return await (0, import_wiki_graph_core5.listArchiveEvidence)(document, objectUri, {
2584
+ return await (0, import_wiki_graph_core7.listArchiveEvidence)(document, objectUri, {
2743
2585
  ...withoutOperation(options),
2744
2586
  ...chapters === void 0 ? {} : { chapters }
2745
2587
  });
@@ -2752,7 +2594,7 @@ var WikiGraphArchiveHandle = class {
2752
2594
  }
2753
2595
  async pack(objectUri = this.objectUri, budget = 5e3, options = {}) {
2754
2596
  return await this.#readDocument(
2755
- async (document) => await (0, import_wiki_graph_core5.packArchiveContext)(document, objectUri, budget),
2597
+ async (document) => await (0, import_wiki_graph_core7.packArchiveContext)(document, objectUri, budget),
2756
2598
  options
2757
2599
  );
2758
2600
  }
@@ -2775,7 +2617,7 @@ var WikiGraphArchiveHandle = class {
2775
2617
  }, options);
2776
2618
  }
2777
2619
  async readCover(options = {}) {
2778
- const app = new import_wiki_graph_core5.WikiGraph({});
2620
+ const app = new import_wiki_graph_core7.WikiGraph({});
2779
2621
  return await this.#runtime.run(
2780
2622
  async () => await app.openSession(
2781
2623
  this.#location.archiveFile,
@@ -2823,7 +2665,7 @@ var WikiGraphArchiveHandle = class {
2823
2665
  }
2824
2666
  async #readDocument(operation, options = {}) {
2825
2667
  return await this.#runtime.run(
2826
- async () => await new import_wiki_graph_core5.WikiGraphArchiveFile(this.#location.archiveFile).readDocument(
2668
+ async () => await new import_wiki_graph_core7.WikiGraphArchiveFile(this.#location.archiveFile).readDocument(
2827
2669
  operation
2828
2670
  ),
2829
2671
  options.signal
@@ -2831,17 +2673,13 @@ var WikiGraphArchiveHandle = class {
2831
2673
  }
2832
2674
  async #writeDocument(operation, options = {}) {
2833
2675
  return await this.#runtime.run(async () => {
2834
- const result = await new import_wiki_graph_core5.WikiGraphArchiveFile(
2835
- this.#location.archiveFile
2836
- ).write(operation, {
2676
+ return await writeWikiGraphArchiveLocation(this.#location, operation, {
2677
+ ...options.onIndexSyncError === void 0 ? {} : { onIndexSyncError: options.onIndexSyncError },
2678
+ ...options.refreshLibraryIndex === void 0 ? {} : { refreshLibraryIndex: options.refreshLibraryIndex },
2837
2679
  ...options.searchIndexWritebackPolicy === void 0 ? {} : {
2838
2680
  searchIndexWritebackPolicy: options.searchIndexWritebackPolicy
2839
2681
  }
2840
2682
  });
2841
- if (options.refreshLibraryIndex !== false) {
2842
- await this.#refreshLibraryIndex(options.onIndexSyncError);
2843
- }
2844
- return result;
2845
2683
  }, options.signal);
2846
2684
  }
2847
2685
  async #resolveScope(document, options) {
@@ -2851,7 +2689,7 @@ var WikiGraphArchiveHandle = class {
2851
2689
  async #resolveQueryChapters(document, options) {
2852
2690
  const chapters = await this.#resolveScope(document, options);
2853
2691
  if (options.skipUnindexed !== true) return chapters;
2854
- const queryable = await (0, import_wiki_graph_core5.listArchiveQueryableChapterIds)(document, {
2692
+ const queryable = await (0, import_wiki_graph_core7.listArchiveQueryableChapterIds)(document, {
2855
2693
  ...chapters === void 0 ? {} : { chapters }
2856
2694
  });
2857
2695
  if (queryable.length === 0) {
@@ -2861,56 +2699,11 @@ var WikiGraphArchiveHandle = class {
2861
2699
  }
2862
2700
  return queryable;
2863
2701
  }
2864
- async #refreshLibraryIndex(onError) {
2865
- if (this.#location.libraryDirtyTarget === void 0) return;
2866
- if (this.#location.libraryArchiveTarget !== void 0) {
2867
- await (0, import_wiki_graph_core5.finalizeWikiGraphLibraryArchiveWrite)({
2868
- target: this.#location.libraryArchiveTarget
2869
- });
2870
- }
2871
- try {
2872
- const state = await (0, import_wiki_graph_core5.readWikiGraphLibraryIndexState)(
2873
- this.#location.libraryDirtyTarget
2874
- );
2875
- if (state.status !== "missing") {
2876
- await (0, import_wiki_graph_core5.rebuildWikiGraphLibraryIndex)(this.#location.libraryDirtyTarget);
2877
- }
2878
- } catch (error) {
2879
- onError?.(error);
2880
- }
2881
- }
2882
2702
  };
2883
- async function resolveWikiGraphArchiveLocation(uriOrPath) {
2884
- if (!uriOrPath.startsWith("wikg://")) {
2885
- return createPathLocation(resolveWikiGraphRuntimePath(uriOrPath));
2886
- }
2887
- const parsed = (0, import_wiki_graph_core5.parseLocatedWikiGraphUri)(uriOrPath);
2888
- const portableArchiveLocator = parsed.archivePath ?? uriOrPath;
2889
- const archiveLocator = portableArchiveLocator.startsWith("wikg://lib/") ? portableArchiveLocator : resolveWikiGraphRuntimePath(portableArchiveLocator);
2890
- const libraryArchiveTarget = archiveLocator.startsWith("wikg://lib/") ? (0, import_wiki_graph_core5.parseWikiGraphLibraryUri)(archiveLocator) : void 0;
2891
- const archiveFile = libraryArchiveTarget?.kind === "archive" ? await (0, import_wiki_graph_core5.resolveWikiGraphLibraryArchiveFile)(archiveLocator) : new NodeFile(archiveLocator);
2892
- const archivePath = getNodeResourcePath(archiveFile);
2893
- return {
2894
- archiveFile,
2895
- archiveKey: archivePath,
2896
- archivePath,
2897
- indexScope: { archiveKey: archivePath, archivePath, kind: "archive-index" },
2898
- ...libraryArchiveTarget?.kind === "archive" ? {
2899
- libraryArchiveTarget,
2900
- libraryDirtyTarget: {
2901
- isDefault: libraryArchiveTarget.isDefault,
2902
- kind: "scope",
2903
- ...libraryArchiveTarget.publicId === void 0 ? {} : { publicId: libraryArchiveTarget.publicId }
2904
- },
2905
- publicArchiveUri: portableArchiveLocator
2906
- } : {},
2907
- locatedUri: (0, import_wiki_graph_core5.formatLocatedWikiGraphUri)(archivePath, parsed.objectUri)
2908
- };
2909
- }
2910
2703
  async function ensureArchiveSearchIndex(document, options = {}) {
2911
2704
  const scope = options.chapters === void 0 ? {} : { chapters: options.chapters };
2912
- if (await (0, import_wiki_graph_core5.isArchiveSearchIndexCurrent)(document, scope)) return;
2913
- await (0, import_wiki_graph_core5.rebuildArchiveSearchIndex)(document, void 0, {
2705
+ if (await (0, import_wiki_graph_core7.isArchiveSearchIndexCurrent)(document, scope)) return;
2706
+ await (0, import_wiki_graph_core7.rebuildArchiveSearchIndex)(document, void 0, {
2914
2707
  ...scope,
2915
2708
  ...options.embeddingProvider === void 0 ? {} : { embeddingProvider: options.embeddingProvider }
2916
2709
  });
@@ -2920,10 +2713,10 @@ async function resolveArchiveScope(document, objectUri, depth) {
2920
2713
  if (parsed === void 0 || parsed.kind === "collection" && depth === void 0) {
2921
2714
  return void 0;
2922
2715
  }
2923
- const chapters = await (0, import_wiki_graph_core5.listChapters)(document);
2716
+ const chapters = await (0, import_wiki_graph_core7.listChapters)(document);
2924
2717
  const entries = parsed.kind === "collection" ? chapters.filter((chapter) => chapter.depth <= depth) : selectChapterSubtree(
2925
2718
  chapters,
2926
- await (0, import_wiki_graph_core5.resolveChapterPathReadonly)(document, parsed.chapterPath),
2719
+ await (0, import_wiki_graph_core7.resolveChapterPathReadonly)(document, parsed.chapterPath),
2927
2720
  depth
2928
2721
  );
2929
2722
  return { chapterIds: entries.map((entry) => entry.chapterId), entries };
@@ -2945,32 +2738,23 @@ function selectChapterSubtree(chapters, rootChapterId, depth) {
2945
2738
  (chapter) => chapter.chapterId === root.chapterId || chapter.path.startsWith(prefix) && (depth === void 0 || chapter.depth - root.depth <= depth)
2946
2739
  );
2947
2740
  }
2948
- function createPathLocation(path) {
2949
- return {
2950
- archiveFile: new NodeFile(path),
2951
- archiveKey: path,
2952
- archivePath: path,
2953
- indexScope: { archiveKey: path, archivePath: path, kind: "archive-index" },
2954
- locatedUri: (0, import_wiki_graph_core5.formatLocatedWikiGraphUri)(path)
2955
- };
2956
- }
2957
2741
  async function createEmptyArchiveFile(path) {
2958
- const directoryPath = await (0, import_promises3.mkdtemp)(
2959
- (0, import_path4.join)((0, import_os3.tmpdir)(), "wikigraph-archive-write-")
2742
+ const directoryPath = await (0, import_promises4.mkdtemp)(
2743
+ (0, import_path5.join)((0, import_os3.tmpdir)(), "wikigraph-archive-write-")
2960
2744
  );
2961
2745
  try {
2962
2746
  const directory = new NodeDirectory(directoryPath);
2963
- const document = await import_wiki_graph_core5.DirectoryDocument.open(directory);
2747
+ const document = await import_wiki_graph_core7.DirectoryDocument.open(directory);
2964
2748
  try {
2965
2749
  await document.openSession(async (openedDocument) => {
2966
- await openedDocument.writeToc({ items: [], version: import_wiki_graph_core5.TOC_FILE_VERSION });
2750
+ await openedDocument.writeToc({ items: [], version: import_wiki_graph_core7.TOC_FILE_VERSION });
2967
2751
  });
2968
2752
  } finally {
2969
2753
  await document.release();
2970
2754
  }
2971
- await (0, import_wiki_graph_core5.writeWikgArchive)(directory, new NodeFile(path));
2755
+ await (0, import_wiki_graph_core7.writeWikgArchive)(directory, new NodeFile(path));
2972
2756
  } finally {
2973
- await (0, import_promises3.rm)(directoryPath, { force: true, recursive: true });
2757
+ await (0, import_promises4.rm)(directoryPath, { force: true, recursive: true });
2974
2758
  }
2975
2759
  }
2976
2760
  function isNodeEEXISTError(error) {
@@ -2978,7 +2762,7 @@ function isNodeEEXISTError(error) {
2978
2762
  }
2979
2763
  async function nodePathExists(path) {
2980
2764
  try {
2981
- await (0, import_promises3.stat)(path);
2765
+ await (0, import_promises4.stat)(path);
2982
2766
  return true;
2983
2767
  } catch (error) {
2984
2768
  if (isNodeENOENTError(error)) return false;
@@ -2990,13 +2774,13 @@ function isNodeENOENTError(error) {
2990
2774
  }
2991
2775
  function parseObjectMetadataTarget(objectPath) {
2992
2776
  if (objectPath === "") {
2993
- return { kind: import_wiki_graph_core5.ObjectMetadataKind.Archive, objectPath };
2777
+ return { kind: import_wiki_graph_core7.ObjectMetadataKind.Archive, objectPath };
2994
2778
  }
2995
2779
  const chapter = /^chapter\/([1-9][0-9]*)(?:\/.*)?$/u.exec(objectPath);
2996
2780
  if (chapter?.[1] !== void 0) {
2997
2781
  return {
2998
2782
  chapterId: Number(chapter[1]),
2999
- kind: import_wiki_graph_core5.ObjectMetadataKind.Chapter,
2783
+ kind: import_wiki_graph_core7.ObjectMetadataKind.Chapter,
3000
2784
  objectPath
3001
2785
  };
3002
2786
  }
@@ -3004,7 +2788,7 @@ function parseObjectMetadataTarget(objectPath) {
3004
2788
  if (chunk?.[1] !== void 0) {
3005
2789
  return {
3006
2790
  chunkId: Number(chunk[1]),
3007
- kind: import_wiki_graph_core5.ObjectMetadataKind.Chunk,
2791
+ kind: import_wiki_graph_core7.ObjectMetadataKind.Chunk,
3008
2792
  objectPath
3009
2793
  };
3010
2794
  }
@@ -3012,7 +2796,7 @@ function parseObjectMetadataTarget(objectPath) {
3012
2796
  if (entity?.[1] !== void 0) {
3013
2797
  return {
3014
2798
  entityQid: entity[1],
3015
- kind: import_wiki_graph_core5.ObjectMetadataKind.Entity,
2799
+ kind: import_wiki_graph_core7.ObjectMetadataKind.Entity,
3016
2800
  objectPath
3017
2801
  };
3018
2802
  }
@@ -3021,14 +2805,14 @@ function parseObjectMetadataTarget(objectPath) {
3021
2805
  );
3022
2806
  if (triple?.[1] !== void 0) {
3023
2807
  return {
3024
- kind: import_wiki_graph_core5.ObjectMetadataKind.Triple,
2808
+ kind: import_wiki_graph_core7.ObjectMetadataKind.Triple,
3025
2809
  objectPath,
3026
2810
  tripleObjectQid: triple[3],
3027
2811
  triplePredicate: decodeURIComponent(triple[2]),
3028
2812
  tripleSubjectQid: triple[1]
3029
2813
  };
3030
2814
  }
3031
- return { kind: import_wiki_graph_core5.ObjectMetadataKind.Object, objectPath };
2815
+ return { kind: import_wiki_graph_core7.ObjectMetadataKind.Object, objectPath };
3032
2816
  }
3033
2817
  function withoutOperation(options) {
3034
2818
  const { signal: _signal, ...rest } = options;
@@ -3044,7 +2828,7 @@ function withoutOperationAndScope(options) {
3044
2828
  return rest;
3045
2829
  }
3046
2830
  async function resolveOptionalChapterPath(document, path) {
3047
- return path === void 0 ? void 0 : await (0, import_wiki_graph_core5.resolveChapterPathReadonly)(document, path);
2831
+ return path === void 0 ? void 0 : await (0, import_wiki_graph_core7.resolveChapterPathReadonly)(document, path);
3048
2832
  }
3049
2833
  function requireChapter(chapters, chapterId) {
3050
2834
  const chapter = chapters.find((entry) => entry.chapterId === chapterId);
@@ -3058,7 +2842,7 @@ function asTextStream(text) {
3058
2842
  }
3059
2843
  async function assertChapterResetAllowed(archive, chapterId, stage) {
3060
2844
  if (stage === "planned") {
3061
- await (0, import_wiki_graph_core5.assertNoActiveBuildJobs)({
2845
+ await (0, import_wiki_graph_core7.assertNoActiveBuildJobs)({
3062
2846
  archive,
3063
2847
  chapterIds: [chapterId],
3064
2848
  operation: "Resetting chapter to planned"
@@ -3066,14 +2850,14 @@ async function assertChapterResetAllowed(archive, chapterId, stage) {
3066
2850
  return;
3067
2851
  }
3068
2852
  if (stage === "sourced") {
3069
- await (0, import_wiki_graph_core5.assertNoActiveBuildJobs)({
2853
+ await (0, import_wiki_graph_core7.assertNoActiveBuildJobs)({
3070
2854
  archive,
3071
2855
  chapterIds: [chapterId],
3072
2856
  operation: "Resetting chapter graph",
3073
2857
  requiresTarget: "reading-graph"
3074
2858
  });
3075
2859
  }
3076
- await (0, import_wiki_graph_core5.assertNoActiveBuildJobs)({
2860
+ await (0, import_wiki_graph_core7.assertNoActiveBuildJobs)({
3077
2861
  archive,
3078
2862
  chapterIds: [chapterId],
3079
2863
  operation: "Resetting chapter summary",
@@ -3084,12 +2868,13 @@ async function assertChapterResetAllowed(archive, chapterId, stage) {
3084
2868
  // src/wikispine.ts
3085
2869
  var import_child_process = require("child_process");
3086
2870
  var nodeWikispineCommandRunner = {
3087
- run: async ({ args, command, input, onStdout, signal }) => await new Promise((resolve3, reject) => {
2871
+ run: async ({ args, command, input, onStdout, signal }) => await new Promise((resolve4, reject) => {
3088
2872
  signal?.throwIfAborted();
3089
2873
  const child = (0, import_child_process.spawn)(command, [...args], {
3090
2874
  stdio: ["pipe", "pipe", "pipe"]
3091
2875
  });
3092
2876
  const stderr = [];
2877
+ let stdoutQueue = Promise.resolve();
3093
2878
  let settled = false;
3094
2879
  const settle = (operation) => {
3095
2880
  if (settled) return;
@@ -3105,14 +2890,15 @@ var nodeWikispineCommandRunner = {
3105
2890
  child.stdout.setEncoding("utf8");
3106
2891
  child.stdout.on("data", (chunk) => {
3107
2892
  if (settled) return;
3108
- try {
3109
- onStdout(chunk);
3110
- } catch (error) {
2893
+ child.stdout.pause();
2894
+ stdoutQueue = stdoutQueue.then(async () => await onStdout(chunk)).then(() => {
2895
+ child.stdout.resume();
2896
+ }).catch((error) => {
3111
2897
  child.kill();
3112
2898
  settle(
3113
2899
  () => reject(error instanceof Error ? error : new Error(String(error)))
3114
2900
  );
3115
- }
2901
+ });
3116
2902
  });
3117
2903
  child.stderr.on("data", (chunk) => stderr.push(chunk));
3118
2904
  child.on("error", (error) => {
@@ -3123,12 +2909,14 @@ var nodeWikispineCommandRunner = {
3123
2909
  );
3124
2910
  });
3125
2911
  child.on("close", (exitCode) => {
3126
- settle(
3127
- () => resolve3({
3128
- exitCode,
3129
- stderr: Buffer.concat(stderr).toString("utf8")
3130
- })
3131
- );
2912
+ void stdoutQueue.then(() => {
2913
+ settle(
2914
+ () => resolve4({
2915
+ exitCode,
2916
+ stderr: Buffer.concat(stderr).toString("utf8")
2917
+ })
2918
+ );
2919
+ });
3132
2920
  });
3133
2921
  child.stdin.end(input);
3134
2922
  })
@@ -3139,7 +2927,7 @@ function abortError(signal) {
3139
2927
 
3140
2928
  // src/config.ts
3141
2929
  var import_ai2 = require("ai");
3142
- var import_wiki_graph_core6 = require("wiki-graph-core");
2930
+ var import_wiki_graph_core8 = require("wiki-graph-core");
3143
2931
  var WikiGraphConfigManager = class {
3144
2932
  #runtime;
3145
2933
  constructor(runtime) {
@@ -3222,7 +3010,7 @@ var WikiGraphConfigManager = class {
3222
3010
  if (resolved === void 0) {
3223
3011
  throw new Error("WikiSpine provider is not configured.");
3224
3012
  }
3225
- const result = await (0, import_wiki_graph_core6.testWikispineRuntime)({
3013
+ const result = await (0, import_wiki_graph_core8.testWikispineRuntime)({
3226
3014
  ...resolved,
3227
3015
  ...resolved.provider === "cli" ? { commandRunner: nodeWikispineCommandRunner } : {}
3228
3016
  });
@@ -3245,7 +3033,7 @@ function parseProvider(value) {
3245
3033
  }
3246
3034
 
3247
3035
  // src/continuations.ts
3248
- var import_wiki_graph_core7 = require("wiki-graph-core");
3036
+ var import_wiki_graph_core9 = require("wiki-graph-core");
3249
3037
  var WikiGraphContinuationManager = class {
3250
3038
  #runtime;
3251
3039
  constructor(runtime) {
@@ -3260,13 +3048,13 @@ var WikiGraphContinuationManager = class {
3260
3048
  async create(context, cursor) {
3261
3049
  if (cursor === null || cursor === void 0) return null;
3262
3050
  return await this.#runtime.run(
3263
- async () => await (0, import_wiki_graph_core7.createContinuationCursor)(
3051
+ async () => await (0, import_wiki_graph_core9.createContinuationCursor)(
3264
3052
  createContinuationPayload(context, cursor)
3265
3053
  )
3266
3054
  );
3267
3055
  }
3268
3056
  async #next(options) {
3269
- const cursor = await (0, import_wiki_graph_core7.readContinuationCursor)(options.cursor);
3057
+ const cursor = await (0, import_wiki_graph_core9.readContinuationCursor)(options.cursor);
3270
3058
  const continuationCursor = options.format === void 0 ? cursor : { ...cursor, format: options.format };
3271
3059
  const limit = options.limit ?? 20;
3272
3060
  if (options.archive !== void 0) {
@@ -3291,29 +3079,29 @@ var WikiGraphContinuationManager = class {
3291
3079
  };
3292
3080
  async function continueArchiveCursor(cursor, limit) {
3293
3081
  const location = await resolveWikiGraphArchiveLocation(
3294
- getCursorArchivePath(cursor)
3082
+ archiveTargetFromLogicalLocator(getCursorArchivePath(cursor))
3295
3083
  );
3296
- return await new import_wiki_graph_core7.WikiGraphArchiveFile(location.archiveFile).readDocument(
3084
+ return await new import_wiki_graph_core9.WikiGraphArchiveFile(location.archiveFile).readDocument(
3297
3085
  async (document) => {
3298
3086
  switch (cursor.kind) {
3299
3087
  case "source-locators":
3300
- return await (0, import_wiki_graph_core7.listArchiveSourceLocators)(document, cursor.targetUri, {
3088
+ return await (0, import_wiki_graph_core9.listArchiveSourceLocators)(document, cursor.targetUri, {
3301
3089
  cursor: cursor.cursor,
3302
3090
  limit
3303
3091
  });
3304
3092
  case "collection":
3305
- return await (0, import_wiki_graph_core7.listArchiveCollection)(
3093
+ return await (0, import_wiki_graph_core9.listArchiveCollection)(
3306
3094
  document,
3307
3095
  createCollectionOptions(cursor, limit)
3308
3096
  );
3309
3097
  case "search":
3310
- return await (0, import_wiki_graph_core7.findArchiveObjects)(
3098
+ return await (0, import_wiki_graph_core9.findArchiveObjects)(
3311
3099
  document,
3312
3100
  cursor.query ?? "",
3313
3101
  await createFindOptions(cursor, limit)
3314
3102
  );
3315
3103
  case "evidence":
3316
- return await (0, import_wiki_graph_core7.listArchiveEvidence)(document, cursor.targetUri, {
3104
+ return await (0, import_wiki_graph_core9.listArchiveEvidence)(document, cursor.targetUri, {
3317
3105
  ...cursor.chapters === null ? {} : { chapters: cursor.chapters },
3318
3106
  cursor: cursor.cursor,
3319
3107
  limit,
@@ -3323,7 +3111,7 @@ async function continueArchiveCursor(cursor, limit) {
3323
3111
  ...cursor.sourceContext === void 0 ? {} : { sourceContext: cursor.sourceContext }
3324
3112
  });
3325
3113
  case "related":
3326
- return await (0, import_wiki_graph_core7.listRelatedArchiveObjects)(document, cursor.targetUri, {
3114
+ return await (0, import_wiki_graph_core9.listRelatedArchiveObjects)(document, cursor.targetUri, {
3327
3115
  ...cursor.chapters === null ? {} : { chapters: cursor.chapters },
3328
3116
  cursor: cursor.cursor,
3329
3117
  ...cursor.evidenceLimit === void 0 ? {} : { evidenceLimit: cursor.evidenceLimit },
@@ -3347,30 +3135,30 @@ async function continueLibraryCursor(cursor, limit) {
3347
3135
  if (cursor.indexScope.kind !== "library-index") {
3348
3136
  throw new Error("Internal error: expected a library index cursor.");
3349
3137
  }
3350
- const target = await (0, import_wiki_graph_core7.resolveWikiGraphLibraryQueryTargetById)(
3138
+ const target = await (0, import_wiki_graph_core9.resolveWikiGraphLibraryQueryTargetById)(
3351
3139
  cursor.indexScope.libraryId
3352
3140
  );
3353
3141
  switch (cursor.kind) {
3354
3142
  case "collection":
3355
- return await (requireLibraryQuery(cursor) === "archive-members" ? (0, import_wiki_graph_core7.listWikiGraphLibraryArchiveMembers)(
3143
+ return await (requireLibraryQuery(cursor) === "archive-members" ? (0, import_wiki_graph_core9.listWikiGraphLibraryArchiveMembers)(
3356
3144
  target,
3357
3145
  createCollectionOptions(cursor, limit)
3358
- ) : (0, import_wiki_graph_core7.listWikiGraphLibraryObjects)(
3146
+ ) : (0, import_wiki_graph_core9.listWikiGraphLibraryObjects)(
3359
3147
  target,
3360
3148
  createCollectionOptions(cursor, limit)
3361
3149
  ));
3362
3150
  case "search":
3363
- return await (requireLibraryQuery(cursor) === "archive-members" ? (0, import_wiki_graph_core7.findWikiGraphLibraryArchiveMembers)(
3151
+ return await (requireLibraryQuery(cursor) === "archive-members" ? (0, import_wiki_graph_core9.findWikiGraphLibraryArchiveMembers)(
3364
3152
  target,
3365
3153
  cursor.query ?? "",
3366
3154
  await createFindOptions(cursor, limit)
3367
- ) : (0, import_wiki_graph_core7.findWikiGraphLibraryObjects)(
3155
+ ) : (0, import_wiki_graph_core9.findWikiGraphLibraryObjects)(
3368
3156
  target,
3369
3157
  cursor.query ?? "",
3370
3158
  await createFindOptions(cursor, limit)
3371
3159
  ));
3372
3160
  case "evidence":
3373
- return await (0, import_wiki_graph_core7.listWikiGraphLibraryEvidence)(target, cursor.targetUri, {
3161
+ return await (0, import_wiki_graph_core9.listWikiGraphLibraryEvidence)(target, cursor.targetUri, {
3374
3162
  cursor: cursor.cursor,
3375
3163
  limit,
3376
3164
  order: cursor.order,
@@ -3379,7 +3167,7 @@ async function continueLibraryCursor(cursor, limit) {
3379
3167
  ...cursor.sourceContext === void 0 ? {} : { sourceContext: cursor.sourceContext }
3380
3168
  });
3381
3169
  case "related":
3382
- return await (0, import_wiki_graph_core7.listRelatedWikiGraphLibraryObjects)(
3170
+ return await (0, import_wiki_graph_core9.listRelatedWikiGraphLibraryObjects)(
3383
3171
  target,
3384
3172
  cursor.targetUri,
3385
3173
  {
@@ -3440,7 +3228,7 @@ function getCursorArchivePath(cursor) {
3440
3228
  }
3441
3229
  async function persistResultCursor(cursor, result) {
3442
3230
  if (result.nextCursor === null) return result;
3443
- const nextCursor = await (0, import_wiki_graph_core7.createContinuationCursor)({
3231
+ const nextCursor = await (0, import_wiki_graph_core9.createContinuationCursor)({
3444
3232
  ...cursor,
3445
3233
  cursor: result.nextCursor
3446
3234
  });
@@ -3543,17 +3331,17 @@ function createLibraryQueryPayload(context) {
3543
3331
  }
3544
3332
 
3545
3333
  // src/default-worker.ts
3546
- var import_wiki_graph_core12 = require("wiki-graph-core");
3334
+ var import_wiki_graph_core14 = require("wiki-graph-core");
3547
3335
  var import_worker3 = require("wiki-graph-core/worker");
3548
3336
 
3549
3337
  // src/stage.ts
3550
- var import_wiki_graph_core8 = require("wiki-graph-core");
3551
- var import_wiki_graph_core9 = require("wiki-graph-core");
3552
3338
  var import_wiki_graph_core10 = require("wiki-graph-core");
3339
+ var import_wiki_graph_core11 = require("wiki-graph-core");
3340
+ var import_wiki_graph_core12 = require("wiki-graph-core");
3553
3341
  function createStageLLM(config, options) {
3554
3342
  const llmOptions = buildWikiGraphLLMOptions(config);
3555
- return new import_wiki_graph_core10.LLM({
3556
- sampling: (0, import_wiki_graph_core9.createDefaultWikiGraphSampling)({
3343
+ return new import_wiki_graph_core12.LLM({
3344
+ sampling: (0, import_wiki_graph_core11.createDefaultWikiGraphSampling)({
3557
3345
  ...llmOptions.temperature === void 0 ? {} : { temperature: llmOptions.temperature },
3558
3346
  ...llmOptions.topP === void 0 ? {} : { topP: llmOptions.topP }
3559
3347
  }),
@@ -3576,9 +3364,134 @@ async function loadRequiredStageConfig(options) {
3576
3364
  return config;
3577
3365
  }
3578
3366
 
3367
+ // src/planning.ts
3368
+ var DEFAULT_GENERATION_JOB_CONCURRENCY = 3;
3369
+ var DEFAULT_GENERATION_REQUEST_CONCURRENCY = 6;
3370
+ function planGenerationTask(task, words, chapters, concurrent, model) {
3371
+ const profile = getGenerationPlanningProfile(task);
3372
+ const calls = Math.max(chapters, Math.ceil(words / profile.wordsPerCall));
3373
+ const effectiveConcurrency = Math.max(
3374
+ 1,
3375
+ task === "reading-graph" ? 1 : concurrent.request
3376
+ );
3377
+ const callBatches = Math.ceil(calls / effectiveConcurrency);
3378
+ const wordSeconds = words * profile.secondsPerWord;
3379
+ return {
3380
+ model,
3381
+ timeSeconds: {
3382
+ max: Math.ceil(callBatches * profile.maxSecondsPerCall + wordSeconds),
3383
+ min: Math.ceil(callBatches * profile.minSecondsPerCall + wordSeconds)
3384
+ },
3385
+ tokens: {
3386
+ cacheableInput: Math.ceil(words * profile.cacheableInputTokenPerWord),
3387
+ input: Math.ceil(words * profile.inputTokenPerWord),
3388
+ output: Math.ceil(words * profile.outputTokenPerWord)
3389
+ }
3390
+ };
3391
+ }
3392
+ function createGenerationPerformanceHints(input) {
3393
+ if (!input.hasJobWork) {
3394
+ return [];
3395
+ }
3396
+ const hints = [];
3397
+ const recommendedRequest = input.concurrent.request < 4 ? DEFAULT_GENERATION_REQUEST_CONCURRENCY : input.concurrent.request < 8 ? 8 : void 0;
3398
+ if (input.hasRequestWork && recommendedRequest !== void 0) {
3399
+ hints.push({
3400
+ configKey: "request",
3401
+ configValue: recommendedRequest,
3402
+ current: input.concurrent.request,
3403
+ kind: "request",
3404
+ message: "LLM request concurrency can often be higher. Use at least 4; 6-8 is usually faster when the provider allows it.",
3405
+ recommended: recommendedRequest
3406
+ });
3407
+ }
3408
+ if (input.concurrent.job < 4 && input.chapters > 1) {
3409
+ hints.push({
3410
+ configKey: "job",
3411
+ configValue: 4,
3412
+ current: input.concurrent.job,
3413
+ kind: "job",
3414
+ message: "Multiple chapters need work and job concurrency is below 4. Raising it lets chapter jobs run in parallel.",
3415
+ recommended: 4
3416
+ });
3417
+ }
3418
+ return hints;
3419
+ }
3420
+ function formatGenerationPlanningModel(llm) {
3421
+ if (llm?.model === void 0) {
3422
+ return "not configured";
3423
+ }
3424
+ return llm.provider === void 0 ? llm.model : `${llm.provider}/${llm.model}`;
3425
+ }
3426
+ function formatGenerationPlanningDuration(seconds) {
3427
+ if (seconds < 60) {
3428
+ return `${seconds}s`;
3429
+ }
3430
+ const minutes = Math.round(seconds / 60);
3431
+ if (minutes < 60) {
3432
+ return `${minutes}m`;
3433
+ }
3434
+ return `${Math.round(minutes / 60)}h`;
3435
+ }
3436
+ function getGenerationPlanningProfile(task) {
3437
+ switch (task) {
3438
+ case "index-fts":
3439
+ return {
3440
+ cacheableInputTokenPerWord: 0,
3441
+ inputTokenPerWord: 0,
3442
+ maxSecondsPerCall: 1,
3443
+ minSecondsPerCall: 0,
3444
+ outputTokenPerWord: 0,
3445
+ secondsPerWord: 5e-4,
3446
+ wordsPerCall: 1e5
3447
+ };
3448
+ case "index-embedding-source":
3449
+ case "index-embedding-summary":
3450
+ return {
3451
+ cacheableInputTokenPerWord: 0,
3452
+ inputTokenPerWord: 0,
3453
+ maxSecondsPerCall: 10,
3454
+ minSecondsPerCall: 1,
3455
+ outputTokenPerWord: 0,
3456
+ secondsPerWord: 2e-3,
3457
+ wordsPerCall: 1e4
3458
+ };
3459
+ case "knowledge-graph":
3460
+ return {
3461
+ cacheableInputTokenPerWord: 60,
3462
+ inputTokenPerWord: 80,
3463
+ maxSecondsPerCall: 35,
3464
+ minSecondsPerCall: 15,
3465
+ outputTokenPerWord: 25,
3466
+ secondsPerWord: 0.02,
3467
+ wordsPerCall: 35
3468
+ };
3469
+ case "reading-graph":
3470
+ return {
3471
+ cacheableInputTokenPerWord: 20,
3472
+ inputTokenPerWord: 25,
3473
+ maxSecondsPerCall: 45,
3474
+ minSecondsPerCall: 15,
3475
+ outputTokenPerWord: 4,
3476
+ secondsPerWord: 0.01,
3477
+ wordsPerCall: 160
3478
+ };
3479
+ case "reading-summary":
3480
+ return {
3481
+ cacheableInputTokenPerWord: 45,
3482
+ inputTokenPerWord: 55,
3483
+ maxSecondsPerCall: 25,
3484
+ minSecondsPerCall: 10,
3485
+ outputTokenPerWord: 4,
3486
+ secondsPerWord: 0.01,
3487
+ wordsPerCall: 110
3488
+ };
3489
+ }
3490
+ }
3491
+
3579
3492
  // src/worker.ts
3580
3493
  var import_worker = require("wiki-graph-core/worker");
3581
- var import_wiki_graph_core11 = require("wiki-graph-core");
3494
+ var import_wiki_graph_core13 = require("wiki-graph-core");
3582
3495
  var import_worker2 = require("wiki-graph-core/worker");
3583
3496
  async function runBuildJobWorker(options) {
3584
3497
  installNodeWikiGraphPlatform();
@@ -3595,7 +3508,7 @@ async function runWikiGraphQueueWorker(options = {}) {
3595
3508
  await runBuildJobWorker({
3596
3509
  concurrency: config.concurrent?.job ?? DEFAULT_GENERATION_JOB_CONCURRENCY,
3597
3510
  executeJob: async (job, reporter, context) => {
3598
- await (0, import_wiki_graph_core12.withLoggingContext)(
3511
+ await (0, import_wiki_graph_core14.withLoggingContext)(
3599
3512
  { logDirectory: job.log, operation: "build-job" },
3600
3513
  async () => await executeBuildJob(job, reporter, context)
3601
3514
  );
@@ -3667,9 +3580,9 @@ async function executeStep(job, kind, execution, reporter, context, inputOptions
3667
3580
  const stepWorkspace = await resetStepWorkspace(job.workspace, kind);
3668
3581
  const inputFile = await stepWorkspace.createFile("input.jsonl");
3669
3582
  const outputWorkspace = await stepWorkspace.createDirectory("output");
3670
- const revision = await new import_wiki_graph_core12.WikiGraphArchiveFile(job.archive).readDocument(
3583
+ const revision = await new import_wiki_graph_core14.WikiGraphArchiveFile(job.archive).readDocument(
3671
3584
  async (document) => {
3672
- await (0, import_wiki_graph_core12.getChapterDetails)(document, job.chapterId);
3585
+ await (0, import_wiki_graph_core14.getChapterDetails)(document, job.chapterId);
3673
3586
  return await (0, import_worker3.writeChapterJobInputFile)(
3674
3587
  document,
3675
3588
  job.chapterId,
@@ -3679,7 +3592,7 @@ async function executeStep(job, kind, execution, reporter, context, inputOptions
3679
3592
  );
3680
3593
  }
3681
3594
  );
3682
- await (0, import_wiki_graph_core12.recordBuildJobInputRevision)({
3595
+ await (0, import_wiki_graph_core14.recordBuildJobInputRevision)({
3683
3596
  currentRevision: revision,
3684
3597
  jobId: job.jobId,
3685
3598
  ownerId: requireRunningJobOwnerId(job)
@@ -3709,16 +3622,23 @@ async function executeStep(job, kind, execution, reporter, context, inputOptions
3709
3622
  total: 1,
3710
3623
  unit: "item"
3711
3624
  });
3712
- await new import_wiki_graph_core12.WikiGraphArchiveFile(job.archive).write(async (document) => {
3713
- assertJobStillRunning(await (0, import_wiki_graph_core12.getBuildJob)(job.jobId));
3714
- await (0, import_worker3.applyChapterJobArtifactFile)(
3715
- document,
3716
- job.chapterId,
3717
- kind,
3718
- revision,
3719
- result.artifactFile
3720
- );
3721
- });
3625
+ const target = await resolveWikiGraphArchiveTarget(job.archive);
3626
+ const resolvedLocation = await resolveWikiGraphArchiveLocation(target);
3627
+ const location = target.kind === "standalone" ? { ...resolvedLocation, archiveFile: job.archive } : resolvedLocation;
3628
+ await writeWikiGraphArchiveLocation(
3629
+ location,
3630
+ async (document) => {
3631
+ assertJobStillRunning(await (0, import_wiki_graph_core14.getBuildJob)(job.jobId));
3632
+ await (0, import_worker3.applyChapterJobArtifactFile)(
3633
+ document,
3634
+ job.chapterId,
3635
+ kind,
3636
+ revision,
3637
+ result.artifactFile
3638
+ );
3639
+ },
3640
+ { invalidateContinuationCursors: true }
3641
+ );
3722
3642
  await reporter.updatePhase({
3723
3643
  done: 1,
3724
3644
  phase: "committing",
@@ -3726,7 +3646,7 @@ async function executeStep(job, kind, execution, reporter, context, inputOptions
3726
3646
  unit: "item"
3727
3647
  });
3728
3648
  await reporter.stepCompleted(kind);
3729
- assertJobStillRunning(await (0, import_wiki_graph_core12.getBuildJob)(job.jobId));
3649
+ assertJobStillRunning(await (0, import_wiki_graph_core14.getBuildJob)(job.jobId));
3730
3650
  }
3731
3651
  async function openJobExecutor(job, config, signal, reporter) {
3732
3652
  const generation = !job.target.startsWith("index-");
@@ -3745,18 +3665,22 @@ async function openJobExecutor(job, config, signal, reporter) {
3745
3665
  const request = llm === void 0 ? void 0 : async (messages, index, maxRetries) => await llm.request(messages, {
3746
3666
  retryIndex: index,
3747
3667
  retryMax: maxRetries,
3748
- scope: import_wiki_graph_core12.WikiGraphScope.ReaderExtraction,
3668
+ scope: import_wiki_graph_core14.WikiGraphScope.ReaderExtraction,
3749
3669
  signal
3750
3670
  });
3751
3671
  if (request !== void 0 && llm !== void 0) {
3752
3672
  request.lazy = async (operation) => await llm.request(async () => await operation(request));
3753
3673
  }
3754
- const wikimediaResolver = job.target !== "knowledge-graph" ? void 0 : await (0, import_wiki_graph_core12.openWikimediaResolver)(
3674
+ const wikimediaResolver = job.target !== "knowledge-graph" ? void 0 : await (0, import_wiki_graph_core14.openWikimediaResolver)(
3755
3675
  config.wikimedia === void 0 ? {
3756
3676
  kind: "local",
3757
3677
  llmRequest: requireValue(
3758
3678
  request,
3759
3679
  "Local Wikimedia resolution requires an LLM."
3680
+ ),
3681
+ llmModelId: requireValue(
3682
+ stageConfig?.llm?.model,
3683
+ "Local Wikimedia resolution requires an LLM model."
3760
3684
  )
3761
3685
  } : {
3762
3686
  endpoint: config.wikimedia.endpoint,
@@ -3780,9 +3704,9 @@ async function openJobExecutor(job, config, signal, reporter) {
3780
3704
  }
3781
3705
  }
3782
3706
  }),
3783
- ...promptSource === void 0 ? {} : { extractionPrompt: (0, import_wiki_graph_core8.resolveExtractionPrompt)(promptSource) },
3707
+ ...promptSource === void 0 ? {} : { extractionPrompt: (0, import_wiki_graph_core10.resolveExtractionPrompt)(promptSource) },
3784
3708
  ...promptSource === void 0 ? {} : {
3785
- knowledgeGraphPrompt: (0, import_wiki_graph_core8.resolveKnowledgeGraphRecallPrompt)(promptSource)
3709
+ knowledgeGraphPrompt: (0, import_wiki_graph_core10.resolveKnowledgeGraphRecallPrompt)(promptSource)
3786
3710
  }
3787
3711
  };
3788
3712
  }
@@ -3794,12 +3718,12 @@ async function resetStepWorkspace(workspace, kind) {
3794
3718
  return await workspace.createDirectory(name);
3795
3719
  }
3796
3720
  async function readChapterStage(job) {
3797
- return await new import_wiki_graph_core12.WikiGraphArchiveFile(job.archive).readDocument(
3798
- async (document) => (await (0, import_wiki_graph_core12.getChapterDetails)(document, job.chapterId)).stage
3721
+ return await new import_wiki_graph_core14.WikiGraphArchiveFile(job.archive).readDocument(
3722
+ async (document) => (await (0, import_wiki_graph_core14.getChapterDetails)(document, job.chapterId)).stage
3799
3723
  );
3800
3724
  }
3801
3725
  async function assertCurrentFtsArtifact(job) {
3802
- await new import_wiki_graph_core12.WikiGraphArchiveFile(job.archive).readDocument(async (document) => {
3726
+ await new import_wiki_graph_core14.WikiGraphArchiveFile(job.archive).readDocument(async (document) => {
3803
3727
  const revision = await document.serials.getRevision(job.chapterId);
3804
3728
  const artifact = await document.indexArtifacts.get(job.chapterId, "fts");
3805
3729
  if (artifact?.sourceRevision !== revision) {
@@ -3898,27 +3822,27 @@ function normalizeOptionalPath(path) {
3898
3822
  }
3899
3823
 
3900
3824
  // src/jobs.ts
3901
- var import_wiki_graph_core13 = require("wiki-graph-core");
3825
+ var import_wiki_graph_core15 = require("wiki-graph-core");
3902
3826
  var TERMINAL_STATES = /* @__PURE__ */ new Set(["canceled", "failed", "succeeded"]);
3903
3827
  var TERMINAL_EVENT_GRACE_READS = 3;
3904
3828
  var CORE_BUILD_JOB_BACKEND = {
3905
- add: async (options) => await (0, import_wiki_graph_core13.addBuildJob)(options),
3906
- boost: async (jobId) => await (0, import_wiki_graph_core13.boostBuildJob)(jobId),
3907
- cancel: async (jobId) => await (0, import_wiki_graph_core13.cancelBuildJob)(jobId),
3908
- get: async (jobId) => await (0, import_wiki_graph_core13.getBuildJob)(jobId),
3909
- list: async (options) => await (0, import_wiki_graph_core13.listBuildJobs)(options),
3910
- pause: async (jobId) => await (0, import_wiki_graph_core13.pauseBuildJob)(jobId),
3829
+ add: async (options) => await (0, import_wiki_graph_core15.addBuildJob)(options),
3830
+ boost: async (jobId) => await (0, import_wiki_graph_core15.boostBuildJob)(jobId),
3831
+ cancel: async (jobId) => await (0, import_wiki_graph_core15.cancelBuildJob)(jobId),
3832
+ get: async (jobId) => await (0, import_wiki_graph_core15.getBuildJob)(jobId),
3833
+ list: async (options) => await (0, import_wiki_graph_core15.listBuildJobs)(options),
3834
+ pause: async (jobId) => await (0, import_wiki_graph_core15.pauseBuildJob)(jobId),
3911
3835
  readEventChunk: async (job, cursor) => await readIncrementalBuildJobEvents(job, cursor),
3912
- readEvents: async (job) => await (0, import_wiki_graph_core13.readBuildJobEvents)(job),
3913
- resume: async (jobId) => await (0, import_wiki_graph_core13.resumeBuildJob)(jobId),
3914
- setTarget: async (jobId, target) => await (0, import_wiki_graph_core13.updateBuildJobTarget)(jobId, target)
3836
+ readEvents: async (job) => await (0, import_wiki_graph_core15.readBuildJobEvents)(job),
3837
+ resume: async (jobId) => await (0, import_wiki_graph_core15.resumeBuildJob)(jobId),
3838
+ setTarget: async (jobId, target) => await (0, import_wiki_graph_core15.updateBuildJobTarget)(jobId, target)
3915
3839
  };
3916
3840
  async function readIncrementalBuildJobEvents(job, cursor) {
3917
3841
  let reader;
3918
3842
  try {
3919
3843
  reader = await job.events.openReader();
3920
3844
  } catch {
3921
- return { cursor, events: await (0, import_wiki_graph_core13.readBuildJobEvents)(job) };
3845
+ return { cursor, events: await (0, import_wiki_graph_core15.readBuildJobEvents)(job) };
3922
3846
  }
3923
3847
  try {
3924
3848
  const offset = cursor <= reader.size ? cursor : 0;
@@ -3942,45 +3866,51 @@ var WikiGraphJobManager = class {
3942
3866
  this.#backend = backend;
3943
3867
  }
3944
3868
  async create(options) {
3945
- const job = await this.#runtime.run(
3946
- async () => await this.#backend.add({
3947
- ...options,
3948
- archive: typeof options.archive === "string" ? new NodeFile(resolveWikiGraphRuntimePath(options.archive)) : options.archive
3949
- })
3950
- );
3951
- return this.#createHandle(job);
3869
+ const resolved = await this.#runtime.run(async () => {
3870
+ const location = await resolveWikiGraphArchiveLocation(options.archive);
3871
+ return {
3872
+ job: await this.#backend.add({
3873
+ ...options,
3874
+ archive: location.archiveFile
3875
+ }),
3876
+ target: location.target
3877
+ };
3878
+ });
3879
+ return await this.#createHandle(resolved.job, resolved.target);
3952
3880
  }
3953
3881
  async clean() {
3954
- return await this.#runtime.run(async () => await (0, import_wiki_graph_core13.cleanBuildJobs)());
3882
+ return await this.#runtime.run(async () => await (0, import_wiki_graph_core15.cleanBuildJobs)());
3955
3883
  }
3956
3884
  async get(jobId) {
3957
- return this.#createHandle(
3958
- await this.#runtime.run(async () => await this.#backend.get(jobId))
3885
+ return await this.#runtime.run(
3886
+ async () => await this.#createHandle(await this.#backend.get(jobId))
3959
3887
  );
3960
3888
  }
3961
3889
  async resolveId(reference) {
3962
3890
  return await this.#runtime.run(
3963
- async () => await (0, import_wiki_graph_core13.resolveBuildJobId)(reference)
3891
+ async () => await (0, import_wiki_graph_core15.resolveBuildJobId)(reference)
3964
3892
  );
3965
3893
  }
3966
3894
  async list(options = {}) {
3967
- const jobs = await this.#runtime.run(async () => {
3895
+ return await this.#runtime.run(async () => {
3968
3896
  const normalized = {
3969
3897
  ...options.activeOnly === void 0 ? {} : { activeOnly: options.activeOnly },
3970
3898
  ...options.all === void 0 ? {} : { all: options.all },
3971
3899
  ...options.archive === void 0 ? {} : {
3972
- archive: typeof options.archive === "string" ? new NodeFile(resolveWikiGraphRuntimePath(options.archive)) : options.archive
3900
+ archive: (await resolveWikiGraphArchiveLocation(options.archive)).archiveFile
3973
3901
  }
3974
3902
  };
3975
- return await this.#backend.list(normalized);
3903
+ const jobs = await this.#backend.list(normalized);
3904
+ return await Promise.all(
3905
+ jobs.map(async (job) => await this.#createHandle(job))
3906
+ );
3976
3907
  });
3977
- return jobs.map((job) => this.#createHandle(job));
3978
3908
  }
3979
3909
  async resolveChapters(jobs) {
3980
3910
  return await this.#runtime.run(async () => {
3981
3911
  const jobsByArchive = /* @__PURE__ */ new Map();
3982
3912
  for (const job of jobs) {
3983
- const archivePath = getBuildJobArchivePath(job);
3913
+ const archivePath = getJobArchiveLocator(job);
3984
3914
  const grouped = jobsByArchive.get(archivePath) ?? [];
3985
3915
  grouped.push(job);
3986
3916
  jobsByArchive.set(archivePath, grouped);
@@ -3988,9 +3918,12 @@ var WikiGraphJobManager = class {
3988
3918
  const entries = (await Promise.all(
3989
3919
  [...jobsByArchive].map(async ([archivePath, archiveJobs]) => {
3990
3920
  try {
3991
- const chapters = await new import_wiki_graph_core13.WikiGraphArchiveFile(
3992
- new NodeFile(archivePath)
3993
- ).readDocument(async (document) => await (0, import_wiki_graph_core13.listChapters)(document));
3921
+ const location = await resolveWikiGraphArchiveLocation(
3922
+ archiveJobs[0].archive
3923
+ );
3924
+ const chapters = await new import_wiki_graph_core15.WikiGraphArchiveFile(
3925
+ location.archiveFile
3926
+ ).readDocument(async (document) => await (0, import_wiki_graph_core15.listChapters)(document));
3994
3927
  const chaptersById = new Map(
3995
3928
  chapters.map((chapter) => [chapter.chapterId, chapter])
3996
3929
  );
@@ -4000,7 +3933,7 @@ var WikiGraphJobManager = class {
4000
3933
  [
4001
3934
  job.jobId,
4002
3935
  {
4003
- locatedUri: (0, import_wiki_graph_core13.formatLocatedChapterUri)(
3936
+ locatedUri: (0, import_wiki_graph_core15.formatLocatedChapterUri)(
4004
3937
  archivePath,
4005
3938
  chapter.path
4006
3939
  ),
@@ -4024,62 +3957,78 @@ var WikiGraphJobManager = class {
4024
3957
  async enqueue(options) {
4025
3958
  return await this.#runtime.run(async () => {
4026
3959
  const location = await resolveWikiGraphArchiveLocation(options.archive);
4027
- const target = options.target ?? "reading-summary";
4028
- await validateQueueTargetConfig(target, options.llmJSON);
4029
- const selectedExplicitly = options.chapterId !== void 0 || options.chapterIds !== void 0 || options.chapterPath !== void 0 || options.depth !== void 0;
4030
- const candidates = await new import_wiki_graph_core13.WikiGraphArchiveFile(
4031
- location.archiveFile
4032
- ).readDocument(async (document) => {
4033
- const chapters = await (0, import_wiki_graph_core13.listChapters)(document);
4034
- const selected = await selectQueueChapters(document, chapters, options);
4035
- const checked = await Promise.all(
4036
- selected.map(async (chapter) => ({
4037
- chapter,
4038
- reason: await readQueueReadinessReason(document, chapter, target)
4039
- }))
4040
- );
4041
- return checked;
4042
- });
4043
- const created = [];
4044
- const skipped = [];
4045
- for (const candidate of candidates) {
4046
- if (candidate.reason !== void 0) {
4047
- if (selectedExplicitly && candidates.length === 1) {
4048
- throw new Error(
4049
- formatQueueReadinessError(
4050
- candidate.chapter,
4051
- target,
4052
- candidate.reason
4053
- )
3960
+ return await (0, import_wiki_graph_core15.withArchiveBuildJobCreationLock)(
3961
+ location.archiveFile,
3962
+ async () => {
3963
+ const target = options.target ?? "reading-summary";
3964
+ await validateQueueTargetConfig(target, options.llmJSON);
3965
+ const selectedExplicitly = options.chapterId !== void 0 || options.chapterIds !== void 0 || options.chapterPath !== void 0 || options.depth !== void 0;
3966
+ const candidates = await new import_wiki_graph_core15.WikiGraphArchiveFile(
3967
+ location.archiveFile
3968
+ ).readDocument(async (document) => {
3969
+ const chapters = await (0, import_wiki_graph_core15.listChapters)(document);
3970
+ const selected = await selectQueueChapters(
3971
+ document,
3972
+ chapters,
3973
+ options
4054
3974
  );
4055
- }
4056
- skipped.push({
4057
- chapter: candidate.chapter,
4058
- reason: candidate.reason
4059
- });
4060
- continue;
4061
- }
4062
- try {
4063
- created.push({
4064
- chapter: candidate.chapter,
4065
- job: await this.create({
4066
- archive: location.archiveFile,
4067
- boost: options.boost ?? false,
4068
- chapterId: candidate.chapter.chapterId,
4069
- ...options.llmJSON === void 0 ? {} : { llmJSON: options.llmJSON },
4070
- ...options.prompt === void 0 ? {} : { prompt: options.prompt },
4071
- target
4072
- })
4073
- });
4074
- } catch (error) {
4075
- if (selectedExplicitly && candidates.length === 1) throw error;
4076
- skipped.push({
4077
- chapter: candidate.chapter,
4078
- reason: error instanceof Error ? error.message : String(error)
3975
+ const checked = await Promise.all(
3976
+ selected.map(async (chapter) => ({
3977
+ chapter,
3978
+ reason: await readQueueReadinessReason(
3979
+ document,
3980
+ chapter,
3981
+ target
3982
+ )
3983
+ }))
3984
+ );
3985
+ return checked;
4079
3986
  });
3987
+ const created = [];
3988
+ const skipped = [];
3989
+ for (const candidate of candidates) {
3990
+ if (candidate.reason !== void 0) {
3991
+ if (selectedExplicitly && candidates.length === 1) {
3992
+ throw new Error(
3993
+ formatQueueReadinessError(
3994
+ candidate.chapter,
3995
+ target,
3996
+ candidate.reason
3997
+ )
3998
+ );
3999
+ }
4000
+ skipped.push({
4001
+ chapter: candidate.chapter,
4002
+ reason: candidate.reason
4003
+ });
4004
+ continue;
4005
+ }
4006
+ try {
4007
+ created.push({
4008
+ chapter: candidate.chapter,
4009
+ job: await this.#createHandle(
4010
+ await this.#backend.add({
4011
+ archive: location.archiveFile,
4012
+ boost: options.boost ?? false,
4013
+ chapterId: candidate.chapter.chapterId,
4014
+ ...options.llmJSON === void 0 ? {} : { llmJSON: options.llmJSON },
4015
+ ...options.prompt === void 0 ? {} : { prompt: options.prompt },
4016
+ target
4017
+ }),
4018
+ location.target
4019
+ )
4020
+ });
4021
+ } catch (error) {
4022
+ if (selectedExplicitly && candidates.length === 1) throw error;
4023
+ skipped.push({
4024
+ chapter: candidate.chapter,
4025
+ reason: error instanceof Error ? error.message : String(error)
4026
+ });
4027
+ }
4028
+ }
4029
+ return { created, skipped };
4080
4030
  }
4081
- }
4082
- return { created, skipped };
4031
+ );
4083
4032
  });
4084
4033
  }
4085
4034
  async planEnqueue(options) {
@@ -4088,10 +4037,10 @@ var WikiGraphJobManager = class {
4088
4037
  const target = options.target ?? "reading-summary";
4089
4038
  await validateQueueTargetConfig(target, options.llmJSON);
4090
4039
  const selectedExplicitly = options.chapterId !== void 0 || options.chapterIds !== void 0 || options.chapterPath !== void 0 || options.depth !== void 0;
4091
- const candidates = await new import_wiki_graph_core13.WikiGraphArchiveFile(
4040
+ const candidates = await new import_wiki_graph_core15.WikiGraphArchiveFile(
4092
4041
  location.archiveFile
4093
4042
  ).readDocument(async (document) => {
4094
- const chapters = await (0, import_wiki_graph_core13.listChapters)(document);
4043
+ const chapters = await (0, import_wiki_graph_core15.listChapters)(document);
4095
4044
  const selected = await selectQueueChapters(document, chapters, options);
4096
4045
  return await Promise.all(
4097
4046
  selected.map(async (chapter) => ({
@@ -4125,34 +4074,39 @@ var WikiGraphJobManager = class {
4125
4074
  this.#subscriptions.add(controller);
4126
4075
  return () => this.#subscriptions.delete(controller);
4127
4076
  }
4128
- #createHandle(snapshot) {
4129
- return new WikiGraphJob(this, this.#runtime, this.#backend, snapshot);
4077
+ async #createHandle(snapshot, target) {
4078
+ const legacy = snapshot;
4079
+ const resolvedTarget = target ?? (snapshot.archive === void 0 ? archiveTargetFromLogicalLocator(legacy.archivePath ?? "unknown.wikg") : await resolveWikiGraphArchiveTarget(snapshot.archive));
4080
+ return new WikiGraphJob(
4081
+ this,
4082
+ this.#runtime,
4083
+ this.#backend,
4084
+ snapshot,
4085
+ cloneWikiGraphArchiveTarget(resolvedTarget)
4086
+ );
4130
4087
  }
4131
4088
  };
4132
- function getBuildJobArchivePath(job) {
4133
- const record = job;
4134
- if (record.archive !== void 0) {
4135
- return getNodeResourcePath(record.archive);
4136
- }
4137
- if (typeof record.archivePath === "string") return record.archivePath;
4138
- throw new TypeError("Build job is missing archive");
4089
+ function getJobArchiveLocator(job) {
4090
+ return job.archive.kind === "library" ? job.archive.uri : job.archive.path;
4139
4091
  }
4140
4092
  var WikiGraphJob = class {
4141
4093
  #manager;
4142
4094
  #runtime;
4143
4095
  #backend;
4096
+ #archiveTarget;
4144
4097
  #snapshot;
4145
- constructor(manager, runtime, backend, snapshot) {
4098
+ constructor(manager, runtime, backend, snapshot, archiveTarget) {
4146
4099
  this.#manager = manager;
4147
4100
  this.#runtime = runtime;
4148
4101
  this.#backend = backend;
4149
4102
  this.#snapshot = snapshot;
4103
+ this.#archiveTarget = archiveTarget;
4150
4104
  }
4151
4105
  get id() {
4152
4106
  return this.#snapshot.jobId;
4153
4107
  }
4154
4108
  get snapshot() {
4155
- return this.#snapshot;
4109
+ return toPublicJobSnapshot(this.#snapshot, this.#archiveTarget);
4156
4110
  }
4157
4111
  async status() {
4158
4112
  return await this.#update(async () => await this.#backend.get(this.id));
@@ -4179,7 +4133,8 @@ var WikiGraphJob = class {
4179
4133
  let cursor = 0;
4180
4134
  let job = this.#snapshot;
4181
4135
  if (options.from === "now") {
4182
- job = await this.status();
4136
+ await this.status();
4137
+ job = this.#snapshot;
4183
4138
  const chunk = await this.#readEventChunkSafely(job, cursor);
4184
4139
  const events = chunk.events;
4185
4140
  cursor = chunk.cursor;
@@ -4199,7 +4154,8 @@ var WikiGraphJob = class {
4199
4154
  yield event;
4200
4155
  }
4201
4156
  if (sawTerminalEvent) return;
4202
- job = await this.status();
4157
+ await this.status();
4158
+ job = this.#snapshot;
4203
4159
  if (isTerminalState(job.state)) {
4204
4160
  terminalReadsWithoutEvent += 1;
4205
4161
  if (terminalReadsWithoutEvent >= TERMINAL_EVENT_GRACE_READS) return;
@@ -4236,7 +4192,7 @@ var WikiGraphJob = class {
4236
4192
  }
4237
4193
  async #update(operation) {
4238
4194
  this.#snapshot = await this.#runtime.run(operation);
4239
- return this.#snapshot;
4195
+ return this.snapshot;
4240
4196
  }
4241
4197
  async #readEventChunk(job, cursor) {
4242
4198
  return await this.#runtime.run(async () => {
@@ -4255,6 +4211,54 @@ var WikiGraphJob = class {
4255
4211
  }
4256
4212
  }
4257
4213
  };
4214
+ function toPublicJobSnapshot(job, archive) {
4215
+ const legacy = job;
4216
+ return {
4217
+ archive: cloneWikiGraphArchiveTarget(archive),
4218
+ archiveKey: archive.kind === "library" ? archive.uri : job.archiveKey,
4219
+ ...getJobResourcePath(job.cache, legacy.cachePath) === void 0 ? {} : { cachePath: getJobResourcePath(job.cache, legacy.cachePath) },
4220
+ chapterId: job.chapterId,
4221
+ createdAt: job.createdAt,
4222
+ ...job.currentStep === void 0 ? {} : { currentStep: job.currentStep },
4223
+ ...job.errorJSON === void 0 ? {} : { errorJSON: job.errorJSON },
4224
+ ...getJobResourcePath(job.events, legacy.eventsPath) === void 0 ? {} : { eventsPath: getJobResourcePath(job.events, legacy.eventsPath) },
4225
+ ...job.finishedAt === void 0 ? {} : { finishedAt: job.finishedAt },
4226
+ jobId: job.jobId,
4227
+ ...job.inputRevision === void 0 ? {} : { inputRevision: job.inputRevision },
4228
+ ...getJobResourcePath(job.log, legacy.logPath) === void 0 ? {} : { logPath: getJobResourcePath(job.log, legacy.logPath) },
4229
+ ...job.llmJSON === void 0 ? {} : { llmJSON: job.llmJSON },
4230
+ ...job.ownerId === void 0 ? {} : { ownerId: job.ownerId },
4231
+ ...job.prompt === void 0 ? {} : { prompt: job.prompt },
4232
+ queueRank: job.queueRank,
4233
+ ...job.readingSummaryStartedAt === void 0 ? {} : { readingSummaryStartedAt: job.readingSummaryStartedAt },
4234
+ state: job.state,
4235
+ target: job.target,
4236
+ updatedAt: job.updatedAt,
4237
+ ...getJobResourcePath(job.workspace, legacy.workspacePath) === void 0 ? {} : {
4238
+ workspacePath: getJobResourcePath(
4239
+ job.workspace,
4240
+ legacy.workspacePath
4241
+ )
4242
+ }
4243
+ };
4244
+ }
4245
+ function cloneWikiGraphArchiveTarget(target) {
4246
+ return target.kind === "library" ? Object.freeze({ kind: "library", uri: target.uri }) : Object.freeze({
4247
+ kind: "standalone",
4248
+ path: target.path,
4249
+ ...target.objectUri === void 0 ? {} : { objectUri: target.objectUri }
4250
+ });
4251
+ }
4252
+ function getJobResourcePath(resource, legacy) {
4253
+ if (resource === void 0) return legacy;
4254
+ try {
4255
+ return getNodeResourcePath(resource);
4256
+ } catch {
4257
+ const identity = resource.identity;
4258
+ if (typeof identity === "string") return identity;
4259
+ throw new TypeError("Expected a Node File or Directory resource");
4260
+ }
4261
+ }
4258
4262
  async function selectQueueChapters(document, chapters, options) {
4259
4263
  const ids = options.chapterIds ?? (options.chapterId === void 0 ? void 0 : [options.chapterId]);
4260
4264
  if (ids !== void 0) {
@@ -4265,7 +4269,7 @@ async function selectQueueChapters(document, chapters, options) {
4265
4269
  if (options.chapterPath === void 0) {
4266
4270
  return options.depth === void 0 ? chapters : chapters.filter((chapter) => chapter.depth <= options.depth);
4267
4271
  }
4268
- const rootId = await (0, import_wiki_graph_core13.resolveChapterPathReadonly)(
4272
+ const rootId = await (0, import_wiki_graph_core15.resolveChapterPathReadonly)(
4269
4273
  document,
4270
4274
  options.chapterPath
4271
4275
  );
@@ -4330,14 +4334,14 @@ function formatQueueReadinessError(chapter, target, reason) {
4330
4334
  }
4331
4335
  async function wait(milliseconds, signal) {
4332
4336
  if (signal?.aborted === true) return;
4333
- await new Promise((resolve3) => {
4337
+ await new Promise((resolve4) => {
4334
4338
  let settled = false;
4335
4339
  const complete = () => {
4336
4340
  if (settled) return;
4337
4341
  settled = true;
4338
4342
  clearTimeout(timeout);
4339
4343
  signal?.removeEventListener("abort", complete);
4340
- resolve3();
4344
+ resolve4();
4341
4345
  };
4342
4346
  const timeout = setTimeout(complete, milliseconds);
4343
4347
  signal?.addEventListener("abort", complete, { once: true });
@@ -4359,8 +4363,8 @@ function forwardAbort(source, target) {
4359
4363
  }
4360
4364
 
4361
4365
  // src/libraries.ts
4362
- var import_wiki_graph_core14 = require("wiki-graph-core");
4363
- var import_promises4 = require("fs/promises");
4366
+ var import_wiki_graph_core16 = require("wiki-graph-core");
4367
+ var import_promises5 = require("fs/promises");
4364
4368
  var WikiGraphLibraryManager = class {
4365
4369
  #runtime;
4366
4370
  constructor(runtime) {
@@ -4369,80 +4373,109 @@ var WikiGraphLibraryManager = class {
4369
4373
  async create(folder) {
4370
4374
  const record = await this.#runtime.run(async () => {
4371
4375
  const path = resolveWikiGraphRuntimePath(folder);
4372
- await (0, import_promises4.mkdir)(path);
4373
- return await (0, import_wiki_graph_core14.createWikiGraphLibrary)({ folder: new NodeDirectory(path) });
4376
+ await (0, import_promises5.mkdir)(path);
4377
+ return await (0, import_wiki_graph_core16.createWikiGraphLibrary)({ folder: new NodeDirectory(path) });
4374
4378
  });
4375
4379
  return new WikiGraphLibrary(this.#runtime, record);
4376
4380
  }
4377
- async get(uri = (0, import_wiki_graph_core14.formatWikiGraphLibraryUri)()) {
4381
+ async get(uri = (0, import_wiki_graph_core16.formatWikiGraphLibraryUri)()) {
4378
4382
  const target = requireLibraryTarget(uri);
4379
4383
  const record = await this.#runtime.run(
4380
- async () => await (0, import_wiki_graph_core14.resolveWikiGraphLibrary)(target)
4384
+ async () => await (0, import_wiki_graph_core16.resolveWikiGraphLibrary)(target)
4381
4385
  );
4382
4386
  return new WikiGraphLibrary(this.#runtime, record);
4383
4387
  }
4384
4388
  async addArchive(options) {
4385
- return await this.#runtime.run(
4386
- async () => await (0, import_wiki_graph_core14.addWikiGraphLibraryArchive)({
4387
- inputFile: new NodeFile(
4388
- resolveWikiGraphRuntimePath(options.inputPath)
4389
- ),
4390
- target: requireLibraryTarget(options.target),
4391
- ...options.to === void 0 ? {} : { to: options.to }
4392
- })
4389
+ return toArchiveSnapshot(
4390
+ await this.#runtime.run(
4391
+ async () => await (0, import_wiki_graph_core16.addWikiGraphLibraryArchive)({
4392
+ inputFile: new NodeFile(
4393
+ await assertStandaloneWikiGraphArchivePath(options.inputPath)
4394
+ ),
4395
+ target: requireLibraryTarget(options.target),
4396
+ ...options.to === void 0 ? {} : { to: options.to }
4397
+ })
4398
+ )
4393
4399
  );
4394
4400
  }
4395
4401
  async assertCurrent(target) {
4396
4402
  await this.#runtime.run(
4397
- async () => await (0, import_wiki_graph_core14.assertWikiGraphLibrarySchemaCurrent)(requireLibraryTarget(target))
4403
+ async () => await (0, import_wiki_graph_core16.assertWikiGraphLibrarySchemaCurrent)(requireLibraryTarget(target))
4398
4404
  );
4399
4405
  }
4400
4406
  async rebind(target, folder) {
4401
- return await this.#runtime.run(
4402
- async () => await (0, import_wiki_graph_core14.rebindWikiGraphLibrary)({
4403
- folder: new NodeDirectory(resolveWikiGraphRuntimePath(folder)),
4404
- target: requireLibraryTarget(target)
4405
- })
4407
+ return toScanSnapshot(
4408
+ await this.#runtime.run(
4409
+ async () => await (0, import_wiki_graph_core16.rebindWikiGraphLibrary)({
4410
+ folder: new NodeDirectory(resolveWikiGraphRuntimePath(folder)),
4411
+ target: requireLibraryTarget(target)
4412
+ })
4413
+ )
4406
4414
  );
4407
4415
  }
4408
4416
  async remove(target) {
4409
- return await this.#runtime.run(
4410
- async () => await (0, import_wiki_graph_core14.removeWikiGraphLibrary)(requireLibraryTarget(target))
4417
+ return toLibrarySnapshot(
4418
+ await this.#runtime.run(
4419
+ async () => await (0, import_wiki_graph_core16.removeWikiGraphLibrary)(requireLibraryTarget(target))
4420
+ )
4411
4421
  );
4412
4422
  }
4413
4423
  async scan(target) {
4414
- return await this.#runtime.run(
4415
- async () => await (0, import_wiki_graph_core14.scanWikiGraphLibrary)(requireLibraryTarget(target))
4424
+ return toScanSnapshot(
4425
+ await this.#runtime.run(
4426
+ async () => await (0, import_wiki_graph_core16.scanWikiGraphLibrary)(requireLibraryTarget(target))
4427
+ )
4416
4428
  );
4417
4429
  }
4418
4430
  async getArchive(target) {
4419
- return await this.#runtime.run(
4420
- async () => await (0, import_wiki_graph_core14.getWikiGraphLibraryArchive)(requireLibraryTarget(target))
4431
+ return toArchiveSnapshot(
4432
+ await this.#runtime.run(
4433
+ async () => await (0, import_wiki_graph_core16.getWikiGraphLibraryArchive)(requireLibraryTarget(target))
4434
+ )
4421
4435
  );
4422
4436
  }
4423
4437
  async moveArchive(options) {
4424
- return await this.#runtime.run(
4425
- async () => await (0, import_wiki_graph_core14.moveWikiGraphLibraryArchive)({
4426
- target: requireLibraryTarget(options.target),
4427
- to: options.to
4428
- })
4438
+ return toArchiveSnapshot(
4439
+ await this.#runtime.run(
4440
+ async () => await (0, import_wiki_graph_core16.moveWikiGraphLibraryArchive)({
4441
+ target: requireLibraryTarget(options.target),
4442
+ to: options.to
4443
+ })
4444
+ )
4429
4445
  );
4430
4446
  }
4431
4447
  async removeArchive(target) {
4432
- return await this.#runtime.run(
4433
- async () => await (0, import_wiki_graph_core14.removeWikiGraphLibraryArchive)({
4434
- target: requireLibraryTarget(target)
4448
+ return toArchiveSnapshot(
4449
+ await this.#runtime.run(
4450
+ async () => await (0, import_wiki_graph_core16.removeWikiGraphLibraryArchive)({
4451
+ target: requireLibraryTarget(target)
4452
+ })
4453
+ )
4454
+ );
4455
+ }
4456
+ async replaceArchive(options) {
4457
+ return toArchiveSnapshot(
4458
+ await this.#runtime.run(async () => {
4459
+ const target = requireLibraryTarget(options.target);
4460
+ const current = await (0, import_wiki_graph_core16.getWikiGraphLibraryArchive)(target);
4461
+ return await (0, import_wiki_graph_core16.replaceWikiGraphLibraryArchive)({
4462
+ additionalDerivedStateKeys: current.file === void 0 ? [] : [getNodeResourcePath(current.file)],
4463
+ inputFile: new NodeFile(
4464
+ await assertStandaloneWikiGraphArchivePath(options.inputPath)
4465
+ ),
4466
+ target
4467
+ });
4435
4468
  })
4436
4469
  );
4437
4470
  }
4438
4471
  async indexState(target) {
4439
4472
  return await this.#runtime.run(
4440
- async () => await (0, import_wiki_graph_core14.readWikiGraphLibraryIndexState)(requireLibraryTarget(target))
4473
+ async () => await (0, import_wiki_graph_core16.readWikiGraphLibraryIndexState)(requireLibraryTarget(target))
4441
4474
  );
4442
4475
  }
4443
4476
  async rebuildIndex(target, onProgress) {
4444
4477
  return await this.#runtime.run(
4445
- async () => await (0, import_wiki_graph_core14.rebuildWikiGraphLibraryIndex)(
4478
+ async () => await (0, import_wiki_graph_core16.rebuildWikiGraphLibraryIndex)(
4446
4479
  requireLibraryTarget(target),
4447
4480
  onProgress
4448
4481
  )
@@ -4450,17 +4483,17 @@ var WikiGraphLibraryManager = class {
4450
4483
  }
4451
4484
  async cleanIndex(target) {
4452
4485
  return await this.#runtime.run(
4453
- async () => await (0, import_wiki_graph_core14.cleanWikiGraphLibraryIndex)(requireLibraryTarget(target))
4486
+ async () => await (0, import_wiki_graph_core16.cleanWikiGraphLibraryIndex)(requireLibraryTarget(target))
4454
4487
  );
4455
4488
  }
4456
4489
  async getMetadata(target) {
4457
4490
  return await this.#runtime.run(
4458
- async () => await (0, import_wiki_graph_core14.getWikiGraphLibraryMetadata)(requireLibraryTarget(target))
4491
+ async () => await (0, import_wiki_graph_core16.getWikiGraphLibraryMetadata)(requireLibraryTarget(target))
4459
4492
  );
4460
4493
  }
4461
4494
  async replaceMetadata(target, value) {
4462
4495
  return await this.#runtime.run(
4463
- async () => await (0, import_wiki_graph_core14.replaceWikiGraphLibraryMetadata)(
4496
+ async () => await (0, import_wiki_graph_core16.replaceWikiGraphLibraryMetadata)(
4464
4497
  requireLibraryTarget(target),
4465
4498
  value
4466
4499
  )
@@ -4468,7 +4501,7 @@ var WikiGraphLibraryManager = class {
4468
4501
  }
4469
4502
  async putMetadata(target, key, value) {
4470
4503
  return await this.#runtime.run(
4471
- async () => await (0, import_wiki_graph_core14.putWikiGraphLibraryMetadata)(
4504
+ async () => await (0, import_wiki_graph_core16.putWikiGraphLibraryMetadata)(
4472
4505
  requireLibraryTarget(target),
4473
4506
  key,
4474
4507
  value
@@ -4477,7 +4510,7 @@ var WikiGraphLibraryManager = class {
4477
4510
  }
4478
4511
  async deleteMetadata(target, key) {
4479
4512
  return await this.#runtime.run(
4480
- async () => await (0, import_wiki_graph_core14.deleteWikiGraphLibraryMetadataKey)(
4513
+ async () => await (0, import_wiki_graph_core16.deleteWikiGraphLibraryMetadataKey)(
4481
4514
  requireLibraryTarget(target),
4482
4515
  key
4483
4516
  )
@@ -4485,13 +4518,13 @@ var WikiGraphLibraryManager = class {
4485
4518
  }
4486
4519
  async clearMetadata(target) {
4487
4520
  return await this.#runtime.run(
4488
- async () => await (0, import_wiki_graph_core14.clearWikiGraphLibraryMetadata)(requireLibraryTarget(target))
4521
+ async () => await (0, import_wiki_graph_core16.clearWikiGraphLibraryMetadata)(requireLibraryTarget(target))
4489
4522
  );
4490
4523
  }
4491
4524
  async search(target, query, options = {}) {
4492
4525
  return await this.#runtime.run(async () => {
4493
4526
  const embeddingProvider = await createConfiguredEmbeddingProvider();
4494
- return await (0, import_wiki_graph_core14.findWikiGraphLibraryObjects)(
4527
+ return await (0, import_wiki_graph_core16.findWikiGraphLibraryObjects)(
4495
4528
  requireLibraryTarget(target),
4496
4529
  query,
4497
4530
  {
@@ -4504,7 +4537,7 @@ var WikiGraphLibraryManager = class {
4504
4537
  async searchArchiveMembers(target, query, options = {}) {
4505
4538
  return await this.#runtime.run(async () => {
4506
4539
  const embeddingProvider = await createConfiguredEmbeddingProvider();
4507
- return await (0, import_wiki_graph_core14.findWikiGraphLibraryArchiveMembers)(
4540
+ return await (0, import_wiki_graph_core16.findWikiGraphLibraryArchiveMembers)(
4508
4541
  requireLibraryTarget(target),
4509
4542
  query,
4510
4543
  {
@@ -4516,7 +4549,7 @@ var WikiGraphLibraryManager = class {
4516
4549
  }
4517
4550
  async objects(target, options = {}) {
4518
4551
  return await this.#runtime.run(
4519
- async () => await (0, import_wiki_graph_core14.listWikiGraphLibraryObjects)(
4552
+ async () => await (0, import_wiki_graph_core16.listWikiGraphLibraryObjects)(
4520
4553
  requireLibraryTarget(target),
4521
4554
  options
4522
4555
  )
@@ -4524,7 +4557,7 @@ var WikiGraphLibraryManager = class {
4524
4557
  }
4525
4558
  async archiveMembers(target, options = {}) {
4526
4559
  return await this.#runtime.run(
4527
- async () => await (0, import_wiki_graph_core14.listWikiGraphLibraryArchiveMembers)(
4560
+ async () => await (0, import_wiki_graph_core16.listWikiGraphLibraryArchiveMembers)(
4528
4561
  requireLibraryTarget(target),
4529
4562
  options
4530
4563
  )
@@ -4534,17 +4567,18 @@ var WikiGraphLibraryManager = class {
4534
4567
  return await this.#runtime.run(
4535
4568
  async () => await withConfiguredWikimediaResolver(
4536
4569
  objectUri,
4537
- async (wikimediaOptions) => await (0, import_wiki_graph_core14.readWikiGraphLibraryPage)(
4570
+ async (wikimediaOptions) => await (0, import_wiki_graph_core16.readWikiGraphLibraryPage)(
4538
4571
  requireLibraryTarget(target),
4539
4572
  objectUri,
4540
4573
  { ...options, ...wikimediaOptions }
4541
4574
  )
4542
- )
4575
+ ),
4576
+ options.signal
4543
4577
  );
4544
4578
  }
4545
4579
  async related(target, objectUri, options = {}) {
4546
4580
  return await this.#runtime.run(
4547
- async () => await (0, import_wiki_graph_core14.listRelatedWikiGraphLibraryObjects)(
4581
+ async () => await (0, import_wiki_graph_core16.listRelatedWikiGraphLibraryObjects)(
4548
4582
  requireLibraryTarget(target),
4549
4583
  objectUri,
4550
4584
  options
@@ -4553,7 +4587,7 @@ var WikiGraphLibraryManager = class {
4553
4587
  }
4554
4588
  async evidence(target, objectUri, options = {}) {
4555
4589
  return await this.#runtime.run(
4556
- async () => await (0, import_wiki_graph_core14.listWikiGraphLibraryEvidence)(
4590
+ async () => await (0, import_wiki_graph_core16.listWikiGraphLibraryEvidence)(
4557
4591
  requireLibraryTarget(target),
4558
4592
  objectUri,
4559
4593
  options
@@ -4562,7 +4596,7 @@ var WikiGraphLibraryManager = class {
4562
4596
  }
4563
4597
  async pack(target, objectUri, budget = 5e3) {
4564
4598
  return await this.#runtime.run(
4565
- async () => await (0, import_wiki_graph_core14.packWikiGraphLibraryContext)(
4599
+ async () => await (0, import_wiki_graph_core16.packWikiGraphLibraryContext)(
4566
4600
  requireLibraryTarget(target),
4567
4601
  objectUri,
4568
4602
  budget
@@ -4571,7 +4605,7 @@ var WikiGraphLibraryManager = class {
4571
4605
  }
4572
4606
  async list() {
4573
4607
  const records = await this.#runtime.run(
4574
- async () => await (0, import_wiki_graph_core14.listWikiGraphLibraries)()
4608
+ async () => await (0, import_wiki_graph_core16.listWikiGraphLibraries)()
4575
4609
  );
4576
4610
  return records.map((record) => new WikiGraphLibrary(this.#runtime, record));
4577
4611
  }
@@ -4584,35 +4618,57 @@ var WikiGraphLibrary = class {
4584
4618
  this.#record = record;
4585
4619
  }
4586
4620
  get snapshot() {
4587
- return this.#record;
4621
+ return toLibrarySnapshot(this.#record);
4588
4622
  }
4589
4623
  get uri() {
4590
- return (0, import_wiki_graph_core14.formatWikiGraphLibraryUri)(
4624
+ return (0, import_wiki_graph_core16.formatWikiGraphLibraryUri)(
4591
4625
  this.#record.isDefault ? void 0 : this.#record.publicId
4592
4626
  );
4593
4627
  }
4594
4628
  async archives() {
4595
4629
  const target = requireLibraryTarget(this.uri);
4596
- return await this.#runtime.run(
4597
- async () => await (0, import_wiki_graph_core14.listWikiGraphLibraryArchives)(target)
4598
- );
4630
+ return (await this.#runtime.run(
4631
+ async () => await (0, import_wiki_graph_core16.listWikiGraphLibraryArchives)(target)
4632
+ )).map(toArchiveSnapshot);
4599
4633
  }
4600
4634
  async scan() {
4601
4635
  const target = requireLibraryTarget(this.uri);
4602
- return await this.#runtime.run(
4603
- async () => await (0, import_wiki_graph_core14.scanWikiGraphLibrary)(target)
4636
+ return toScanSnapshot(
4637
+ await this.#runtime.run(async () => await (0, import_wiki_graph_core16.scanWikiGraphLibrary)(target))
4604
4638
  );
4605
4639
  }
4606
4640
  async remove() {
4607
4641
  const target = requireLibraryTarget(this.uri);
4608
- return await this.#runtime.run(
4609
- async () => await (0, import_wiki_graph_core14.removeWikiGraphLibrary)(target)
4642
+ return toLibrarySnapshot(
4643
+ await this.#runtime.run(async () => await (0, import_wiki_graph_core16.removeWikiGraphLibrary)(target))
4610
4644
  );
4611
4645
  }
4612
4646
  };
4647
+ function toLibrarySnapshot(record) {
4648
+ const compatible = record;
4649
+ return {
4650
+ id: record.id,
4651
+ publicId: record.publicId,
4652
+ uri: record.uri,
4653
+ folderPath: compatible.folderPath ?? (record.folder === void 0 ? "" : getNodeResourcePath(record.folder)),
4654
+ isDefault: record.isDefault,
4655
+ createdAt: record.createdAt,
4656
+ updatedAt: record.updatedAt
4657
+ };
4658
+ }
4659
+ function toArchiveSnapshot(record) {
4660
+ const { file: _file, ...snapshot } = record;
4661
+ return snapshot;
4662
+ }
4663
+ function toScanSnapshot(result) {
4664
+ return {
4665
+ ...result.library === void 0 ? {} : { library: toLibrarySnapshot(result.library) },
4666
+ archives: result.archives.map(toArchiveSnapshot)
4667
+ };
4668
+ }
4613
4669
  function requireLibraryTarget(value) {
4614
4670
  if (typeof value !== "string") return value;
4615
- const target = (0, import_wiki_graph_core14.parseWikiGraphLibraryUri)(value);
4671
+ const target = (0, import_wiki_graph_core16.parseWikiGraphLibraryUri)(value);
4616
4672
  if (target === void 0) {
4617
4673
  throw new TypeError(`Invalid Wiki Graph library URI: ${value}`);
4618
4674
  }
@@ -4620,8 +4676,8 @@ function requireLibraryTarget(value) {
4620
4676
  }
4621
4677
 
4622
4678
  // src/maintenance.ts
4623
- var import_wiki_graph_core15 = require("wiki-graph-core");
4624
- var import_path5 = require("path");
4679
+ var import_wiki_graph_core17 = require("wiki-graph-core");
4680
+ var import_path6 = require("path");
4625
4681
  var WikiGraphMaintenanceManager = class {
4626
4682
  #runtime;
4627
4683
  constructor(runtime) {
@@ -4631,22 +4687,22 @@ var WikiGraphMaintenanceManager = class {
4631
4687
  return await this.#runtime.run(
4632
4688
  async () => {
4633
4689
  if (target.kind === "home") {
4634
- return await (0, import_wiki_graph_core15.upgradeWikiGraphMaintenanceTarget)({ kind: "home" });
4690
+ return await (0, import_wiki_graph_core17.upgradeWikiGraphMaintenanceTarget)({ kind: "home" });
4635
4691
  }
4636
4692
  if (target.kind === "library") {
4637
- const parsed = (0, import_wiki_graph_core15.parseWikiGraphLibraryUri)(target.uri);
4693
+ const parsed = (0, import_wiki_graph_core17.parseWikiGraphLibraryUri)(target.uri);
4638
4694
  if (parsed === void 0 || parsed.kind === "archive") {
4639
4695
  throw new Error(
4640
4696
  `Invalid Wiki Graph library upgrade target: ${target.uri}`
4641
4697
  );
4642
4698
  }
4643
- return await (0, import_wiki_graph_core15.upgradeWikiGraphMaintenanceTarget)({
4699
+ return await (0, import_wiki_graph_core17.upgradeWikiGraphMaintenanceTarget)({
4644
4700
  kind: "library",
4645
4701
  target: parsed
4646
4702
  });
4647
4703
  }
4648
- const path = resolveWikiGraphRuntimePath(target.path);
4649
- return await (0, import_wiki_graph_core15.upgradeWikiGraphMaintenanceTarget)({
4704
+ const path = await assertStandaloneWikiGraphArchivePath(target.path);
4705
+ return await (0, import_wiki_graph_core17.upgradeWikiGraphMaintenanceTarget)({
4650
4706
  file: new NodeFile(path),
4651
4707
  kind: "archive"
4652
4708
  });
@@ -4659,9 +4715,9 @@ var WikiGraphMaintenanceManager = class {
4659
4715
  return await this.#runtime.run(async () => {
4660
4716
  const resolvedInputPath = resolveWikiGraphRuntimePath(inputPath);
4661
4717
  const resolvedOutputPath = resolveWikiGraphRuntimePath(outputPath);
4662
- await (0, import_wiki_graph_core15.migrateLegacySdpubToWikg)(
4718
+ await (0, import_wiki_graph_core17.migrateLegacySdpubToWikg)(
4663
4719
  new NodeFile(resolvedInputPath),
4664
- new NodeFile(resolvedOutputPath, (0, import_path5.basename)(resolvedOutputPath))
4720
+ new NodeFile(resolvedOutputPath, (0, import_path6.basename)(resolvedOutputPath))
4665
4721
  );
4666
4722
  return {
4667
4723
  inputPath: resolvedInputPath,
@@ -4675,7 +4731,7 @@ function defaultWikgOutputPath(inputPath) {
4675
4731
  }
4676
4732
 
4677
4733
  // src/sdk.ts
4678
- var import_wiki_graph_core16 = require("wiki-graph-core");
4734
+ var import_wiki_graph_core18 = require("wiki-graph-core");
4679
4735
  var WikiGraphSDK = class {
4680
4736
  #context;
4681
4737
  #homeReady;
@@ -4706,7 +4762,7 @@ var WikiGraphSDK = class {
4706
4762
  throwIfAborted(signal);
4707
4763
  const runWithContext = async () => await withWikiGraphSDKRuntimeContext(this.#context, async () => {
4708
4764
  if (options.skipHomeBootstrap !== true) {
4709
- this.#homeReady ??= (0, import_wiki_graph_core16.ensureWikiGraphHomeSchemaCurrent)().catch(
4765
+ this.#homeReady ??= (0, import_wiki_graph_core18.ensureWikiGraphHomeSchemaCurrent)().catch(
4710
4766
  (error) => {
4711
4767
  this.#homeReady = void 0;
4712
4768
  throw error;
@@ -4736,7 +4792,7 @@ function createWikiGraphSDK(options = {}) {
4736
4792
  }
4737
4793
 
4738
4794
  // src/index.ts
4739
- var import_wiki_graph_core17 = require("wiki-graph-core");
4795
+ var import_wiki_graph_core19 = require("wiki-graph-core");
4740
4796
  // Annotate the CommonJS export names for ESM import in node:
4741
4797
  0 && (module.exports = {
4742
4798
  DANGEROUS_RUNTIME_ENV_NAMES,
@@ -4752,6 +4808,7 @@ var import_wiki_graph_core17 = require("wiki-graph-core");
4752
4808
  WikiGraphArchiveExistsError,
4753
4809
  WikiGraphArchiveHandle,
4754
4810
  WikiGraphArchiveManager,
4811
+ WikiGraphArchiveOwnershipError,
4755
4812
  WikiGraphConfigManager,
4756
4813
  WikiGraphContinuationManager,
4757
4814
  WikiGraphConversionManager,
@@ -4770,7 +4827,6 @@ var import_wiki_graph_core17 = require("wiki-graph-core");
4770
4827
  createNodeTemplateEnvironment,
4771
4828
  createNodeWikiGraphStorage,
4772
4829
  createStageLLM,
4773
- createWikiGraphArchiveInspectReport,
4774
4830
  createWikiGraphSDK,
4775
4831
  deleteLocalConfigValue,
4776
4832
  embedQueryText,
@@ -4788,6 +4844,7 @@ var import_wiki_graph_core17 = require("wiki-graph-core");
4788
4844
  getNodeResourcePath,
4789
4845
  getWikiGraphSDKRuntimeContext,
4790
4846
  getWikiGraphSDKStateDir,
4847
+ inspectWikiGraphArchive,
4791
4848
  installNodeWikiGraphPlatform,
4792
4849
  isSourceLocatorScopeUri,
4793
4850
  isWikiGraphLibraryUri,
@@ -4814,7 +4871,6 @@ var import_wiki_graph_core17 = require("wiki-graph-core");
4814
4871
  resolveExtractionPrompt,
4815
4872
  resolveHostedProviderEndpoint,
4816
4873
  resolveKnowledgeGraphRecallPrompt,
4817
- resolveWikiGraphArchiveLocation,
4818
4874
  resolveWikispineConfig,
4819
4875
  runWikiGraphQueueWorker,
4820
4876
  validateLocalConfigSection,