wiki-graph-sdk 0.9.0 → 0.9.2

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.
Files changed (51) hide show
  1. package/dist/archives.cjs +316 -142
  2. package/dist/archives.cjs.map +1 -1
  3. package/dist/archives.js +326 -148
  4. package/dist/archives.js.map +1 -1
  5. package/dist/conversions.cjs +268 -99
  6. package/dist/conversions.cjs.map +1 -1
  7. package/dist/conversions.js +274 -103
  8. package/dist/conversions.js.map +1 -1
  9. package/dist/default-worker.cjs +258 -101
  10. package/dist/default-worker.cjs.map +1 -1
  11. package/dist/default-worker.js +264 -105
  12. package/dist/default-worker.js.map +1 -1
  13. package/dist/embedding.cjs +214 -54
  14. package/dist/embedding.cjs.map +1 -1
  15. package/dist/embedding.js +214 -54
  16. package/dist/embedding.js.map +1 -1
  17. package/dist/gc.cjs +214 -54
  18. package/dist/gc.cjs.map +1 -1
  19. package/dist/gc.js +214 -54
  20. package/dist/gc.js.map +1 -1
  21. package/dist/index.cjs +354 -174
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +369 -184
  25. package/dist/index.js.map +1 -1
  26. package/dist/local-config.cjs +214 -54
  27. package/dist/local-config.cjs.map +1 -1
  28. package/dist/local-config.js +214 -54
  29. package/dist/local-config.js.map +1 -1
  30. package/dist/maintenance.cjs +264 -97
  31. package/dist/maintenance.cjs.map +1 -1
  32. package/dist/maintenance.js +270 -101
  33. package/dist/maintenance.js.map +1 -1
  34. package/dist/node-platform.cjs +214 -54
  35. package/dist/node-platform.cjs.map +1 -1
  36. package/dist/node-platform.d.ts +2 -0
  37. package/dist/node-platform.js +214 -54
  38. package/dist/node-platform.js.map +1 -1
  39. package/dist/runtime-config.cjs +214 -54
  40. package/dist/runtime-config.cjs.map +1 -1
  41. package/dist/runtime-config.js +214 -54
  42. package/dist/runtime-config.js.map +1 -1
  43. package/dist/stage.cjs +214 -54
  44. package/dist/stage.cjs.map +1 -1
  45. package/dist/stage.js +214 -54
  46. package/dist/stage.js.map +1 -1
  47. package/dist/worker.cjs +257 -96
  48. package/dist/worker.cjs.map +1 -1
  49. package/dist/worker.js +263 -100
  50. package/dist/worker.js.map +1 -1
  51. package/package.json +2 -2
package/dist/index.cjs CHANGED
@@ -61,6 +61,7 @@ __export(src_exports, {
61
61
  WikiGraphLibraryManager: () => WikiGraphLibraryManager,
62
62
  WikiGraphMaintenanceManager: () => WikiGraphMaintenanceManager,
63
63
  WikiGraphSDK: () => WikiGraphSDK,
64
+ WikiGraphSchemaVersionError: () => import_wiki_graph_core19.WikiGraphSchemaVersionError,
64
65
  buildSearchIndexEmbeddingProvider: () => buildSearchIndexEmbeddingProvider,
65
66
  buildWikiGraphLLMOptions: () => buildWikiGraphLLMOptions,
66
67
  clearLocalConfigSection: () => clearLocalConfigSection,
@@ -103,6 +104,7 @@ __export(src_exports, {
103
104
  isSourceLocatorScopeUri: () => import_wiki_graph_core19.isSourceLocatorScopeUri,
104
105
  isWikiGraphJobUri: () => import_wiki_graph_core19.isWikiGraphJobUri,
105
106
  isWikiGraphLibraryUri: () => import_wiki_graph_core19.isWikiGraphLibraryUri,
107
+ isWikiGraphSchemaVersionError: () => import_wiki_graph_core19.isWikiGraphSchemaVersionError,
106
108
  isWikiGraphUri: () => import_wiki_graph_core19.isWikiGraphUri,
107
109
  iterateItems: () => iterateItems,
108
110
  iteratePages: () => iteratePages,
@@ -255,6 +257,15 @@ var NodeFile = class {
255
257
  this.name = name;
256
258
  }
257
259
  path;
260
+ async getPhysicalIdentity() {
261
+ const value = await fsPromises.stat(this.path).catch((error) => {
262
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
263
+ return void 0;
264
+ throw error;
265
+ });
266
+ if (value === void 0) return void 0;
267
+ return `${value.dev}:${value.ino}`;
268
+ }
258
269
  kind = "file";
259
270
  [NODE_RESOURCE_KIND] = "file";
260
271
  identity;
@@ -379,6 +390,15 @@ var NodeDirectory = class _NodeDirectory {
379
390
  this.name = pathModule.basename(path);
380
391
  }
381
392
  path;
393
+ async getPhysicalIdentity() {
394
+ const value = await fsPromises.stat(this.path).catch((error) => {
395
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
396
+ return void 0;
397
+ throw error;
398
+ });
399
+ if (value === void 0) return void 0;
400
+ return `${value.dev}:${value.ino}`;
401
+ }
382
402
  kind = "directory";
383
403
  [NODE_RESOURCE_KIND] = "directory";
384
404
  identity;
@@ -388,8 +408,10 @@ var NodeDirectory = class _NodeDirectory {
388
408
  const file = new NodeFile(pathModule.join(this.path, name));
389
409
  try {
390
410
  return (await fsPromises.stat(file.path)).isFile() ? file : void 0;
391
- } catch {
392
- return void 0;
411
+ } catch (error) {
412
+ if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
413
+ return void 0;
414
+ throw error;
393
415
  }
394
416
  }
395
417
  async getLastModified() {
@@ -407,8 +429,10 @@ var NodeDirectory = class _NodeDirectory {
407
429
  const directory = new _NodeDirectory(pathModule.join(this.path, name));
408
430
  try {
409
431
  return (await fsPromises.stat(directory.path)).isDirectory() ? directory : void 0;
410
- } catch {
411
- return void 0;
432
+ } catch (error) {
433
+ if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
434
+ return void 0;
435
+ throw error;
412
436
  }
413
437
  }
414
438
  async list() {
@@ -532,14 +556,23 @@ async function openNativeNodeDatabase(file, flags) {
532
556
  });
533
557
  });
534
558
  }
535
- async function openNodeZip(file) {
559
+ async function openNodeZip(file, options = {}) {
536
560
  const path = getBrandedNodeResourcePath(file, "file");
537
561
  if (path === void 0) {
538
562
  throw new TypeError("The Node ZIP adapter requires a NodeFile");
539
563
  }
540
- const zipFile = await new Promise((resolve4, reject) => {
541
- yauzl.open(
542
- path,
564
+ const handle = await fsPromises.open(path, "r");
565
+ let size;
566
+ try {
567
+ size = (await handle.stat()).size;
568
+ } catch (error) {
569
+ await handle.close();
570
+ throw error;
571
+ }
572
+ const open2 = () => new Promise((resolve4, reject) => {
573
+ yauzl.fromRandomAccessReader(
574
+ new NodeZipSource(handle),
575
+ size,
543
576
  { autoClose: false, lazyEntries: true },
544
577
  (error, opened) => {
545
578
  if (error || opened === void 0)
@@ -548,63 +581,192 @@ async function openNodeZip(file) {
548
581
  }
549
582
  );
550
583
  });
551
- const entries = await new Promise(
552
- (resolve4, reject) => {
553
- const discovered = /* @__PURE__ */ new Map();
554
- const rejectAndClose = (error) => {
555
- zipFile.close();
556
- reject(
557
- error instanceof Error ? error : new Error("Cannot scan ZIP central directory")
558
- );
559
- };
560
- const resolveEntries = () => {
561
- zipFile.off("error", rejectAndClose);
562
- resolve4(discovered);
563
- };
564
- zipFile.on("entry", (entry) => {
565
- if (!entry.fileName.endsWith("/")) {
566
- discovered.set(entry.fileName, entry);
567
- }
568
- zipFile.readEntry();
569
- });
570
- zipFile.once("error", rejectAndClose);
571
- zipFile.once("end", resolveEntries);
572
- zipFile.readEntry();
573
- }
574
- );
584
+ try {
585
+ (await open2()).close();
586
+ } catch (error) {
587
+ await handle.close();
588
+ throw error;
589
+ }
575
590
  let closed = false;
591
+ let pending = Promise.resolve();
592
+ let closing;
593
+ const run = (operation) => {
594
+ if (closed)
595
+ return Promise.reject(new Error("Cannot read a closed ZIP archive"));
596
+ const result = pending.then(async () => {
597
+ const zip = await open2();
598
+ try {
599
+ return await operation(zip);
600
+ } finally {
601
+ zip.close();
602
+ }
603
+ });
604
+ pending = result.then(
605
+ () => void 0,
606
+ () => void 0
607
+ );
608
+ return result;
609
+ };
610
+ const withEntry = (name, operation) => run(async (zip) => {
611
+ let exact;
612
+ let alias;
613
+ let aliasCollision = false;
614
+ await scanNodeZip(zip, (entry) => {
615
+ if (entry.fileName === name) exact = entry;
616
+ if (normalizeNodeZipName(entry.fileName) === name) {
617
+ if (alias !== void 0 && alias.fileName !== entry.fileName)
618
+ aliasCollision = true;
619
+ alias = entry;
620
+ }
621
+ });
622
+ if ((exact === void 0 || options.entryNameMode === "normalized") && aliasCollision) {
623
+ let bestPosition = -1;
624
+ const candidates = await open2();
625
+ try {
626
+ await scanNodeZip(candidates, async (entry) => {
627
+ if (normalizeNodeZipName(entry.fileName) !== name) return;
628
+ const probe = await open2();
629
+ let position = 0;
630
+ try {
631
+ await scanNodeZip(probe, (candidate) => {
632
+ if (candidate.fileName === entry.fileName) return false;
633
+ position++;
634
+ });
635
+ } finally {
636
+ probe.close();
637
+ }
638
+ if (position >= bestPosition) {
639
+ bestPosition = position;
640
+ alias = entry;
641
+ }
642
+ });
643
+ return await operation(candidates, alias);
644
+ } finally {
645
+ candidates.close();
646
+ }
647
+ }
648
+ return await operation(
649
+ zip,
650
+ options.entryNameMode === "normalized" ? alias : exact ?? alias
651
+ );
652
+ });
576
653
  return {
577
654
  close: () => {
578
- if (!closed) zipFile.close();
579
655
  closed = true;
580
- return Promise.resolve();
656
+ closing ??= pending.then(() => handle.close());
657
+ return closing;
581
658
  },
582
- copyEntry: async (name, target) => {
583
- if (closed) throw new Error("Cannot read a closed ZIP archive");
584
- const entry = entries.get(name);
659
+ copyEntry: (name, target) => withEntry(name, async (zip, entry) => {
585
660
  if (entry === void 0) return false;
586
- await copyNodeZipEntry(zipFile, entry, target);
661
+ await copyNodeZipEntry(zip, entry, target);
587
662
  return true;
588
- },
589
- getEntrySize: (name) => {
590
- if (closed) throw new Error("Cannot read a closed ZIP archive");
591
- return Promise.resolve(entries.get(name)?.uncompressedSize);
592
- },
593
- listEntries: () => Promise.resolve([...entries.keys()]),
594
- readEntryRange: async (name, offset, length) => {
595
- if (closed) throw new Error("Cannot read a closed ZIP archive");
596
- const entry = entries.get(name);
663
+ }),
664
+ getEntrySize: (name) => withEntry(
665
+ name,
666
+ (_zip, entry) => Promise.resolve(entry?.uncompressedSize)
667
+ ),
668
+ listEntries: () => run(async (zip) => {
669
+ const names = /* @__PURE__ */ new Set();
670
+ await scanNodeZip(zip, (entry) => {
671
+ names.add(entry.fileName);
672
+ });
673
+ return [...names];
674
+ }),
675
+ readEntryRange: (name, offset, length) => withEntry(name, async (zip, entry) => {
597
676
  if (entry === void 0) return void 0;
598
- return await readNodeZipEntryRange(zipFile, entry, offset, length);
599
- },
600
- readEntry: async (name) => {
601
- if (closed) throw new Error("Cannot read a closed ZIP archive");
602
- const entry = entries.get(name);
677
+ return await readNodeZipEntryRange(zip, entry, offset, length);
678
+ }),
679
+ readEntry: (name) => withEntry(name, async (zip, entry) => {
603
680
  if (entry === void 0) return void 0;
604
- return await readNodeZipEntry(zipFile, entry);
605
- }
681
+ return await readNodeZipEntry(zip, entry);
682
+ })
606
683
  };
607
684
  }
685
+ var NodeZipSource = class extends yauzl.RandomAccessReader {
686
+ constructor(handle) {
687
+ super();
688
+ this.handle = handle;
689
+ }
690
+ handle;
691
+ read(buffer, offset, length, position, callback) {
692
+ const read2 = (written) => {
693
+ if (written === length) {
694
+ callback(null);
695
+ return;
696
+ }
697
+ fs.read(
698
+ this.handle.fd,
699
+ buffer,
700
+ offset + written,
701
+ length - written,
702
+ position + written,
703
+ (error, bytesRead) => {
704
+ if (error) callback(error);
705
+ else if (bytesRead === 0)
706
+ callback(new Error("Unexpected end of ZIP file"));
707
+ else read2(written + bytesRead);
708
+ }
709
+ );
710
+ };
711
+ read2(0);
712
+ }
713
+ _readStreamForRange(start, end) {
714
+ const handle = this.handle;
715
+ return import_node_stream.Readable.from(
716
+ (async function* () {
717
+ for (let position = start; position < end; ) {
718
+ const buffer = Buffer.allocUnsafe(
719
+ Math.min(64 * 1024, end - position)
720
+ );
721
+ const { bytesRead } = await handle.read(
722
+ buffer,
723
+ 0,
724
+ buffer.length,
725
+ position
726
+ );
727
+ if (bytesRead === 0) return;
728
+ position += bytesRead;
729
+ yield buffer.subarray(0, bytesRead);
730
+ }
731
+ })()
732
+ );
733
+ }
734
+ };
735
+ function normalizeNodeZipName(name) {
736
+ const normalized = name.replaceAll("\\", "/").trim().split("/").filter((part) => part !== "" && part !== ".").join("/");
737
+ return normalized.split("/").includes("..") ? void 0 : normalized;
738
+ }
739
+ async function scanNodeZip(zip, visit) {
740
+ await new Promise((resolve4, reject) => {
741
+ const cleanup = () => {
742
+ zip.off("entry", onEntry);
743
+ zip.off("end", onEnd);
744
+ zip.off("error", onError);
745
+ };
746
+ const onError = (error) => {
747
+ cleanup();
748
+ reject(error);
749
+ };
750
+ const onEnd = () => {
751
+ cleanup();
752
+ resolve4();
753
+ };
754
+ const onEntry = (entry) => {
755
+ void Promise.resolve().then(() => entry.fileName.endsWith("/") ? void 0 : visit(entry)).then((keepReading) => {
756
+ if (keepReading === false) onEnd();
757
+ else zip.readEntry();
758
+ }).catch(
759
+ (error) => onError(
760
+ error instanceof Error ? error : new Error("Cannot scan ZIP", { cause: error })
761
+ )
762
+ );
763
+ };
764
+ zip.on("entry", onEntry);
765
+ zip.once("end", onEnd);
766
+ zip.once("error", onError);
767
+ zip.readEntry();
768
+ });
769
+ }
608
770
  async function copyNodeZipEntry(zipFile, entry, target) {
609
771
  const writer = await target.openWriter();
610
772
  try {
@@ -1505,6 +1667,16 @@ function resolveWikiGraphRuntimePath(path) {
1505
1667
  var import_promises3 = require("fs/promises");
1506
1668
  var import_path3 = require("path");
1507
1669
  var import_wiki_graph_core2 = require("wiki-graph-core");
1670
+ function rethrowArchiveSchemaError(error, target) {
1671
+ if ((0, import_wiki_graph_core2.isWikiGraphSchemaVersionError)(error) && error.target.kind === "archive") {
1672
+ throw new import_wiki_graph_core2.WikiGraphSchemaVersionError(
1673
+ target.kind === "standalone" ? { kind: "archive", path: resolveWikiGraphRuntimePath(target.path) } : { kind: "library", uri: target.uri.split("/arc/")[0] },
1674
+ error.actualVersion,
1675
+ error.supportedVersion
1676
+ );
1677
+ }
1678
+ throw error;
1679
+ }
1508
1680
  function requireWikiGraphArchiveFile(location) {
1509
1681
  return location.archiveFile;
1510
1682
  }
@@ -1525,12 +1697,7 @@ async function assertStandaloneWikiGraphArchivePath(inputPath) {
1525
1697
  const path = resolveWikiGraphRuntimePath(inputPath);
1526
1698
  const candidate = await canonicalPath(path);
1527
1699
  const candidateIdentity = await readFileIdentity(path);
1528
- const libraries = await (0, import_wiki_graph_core2.listWikiGraphLibraries)();
1529
- const matches = await findMatchingMembers(
1530
- libraries,
1531
- candidate,
1532
- candidateIdentity
1533
- );
1700
+ const matches = await findMatchingMembers(candidate, candidateIdentity);
1534
1701
  if (matches.length > 0) {
1535
1702
  const match = requireUnambiguousManagedMatch(path, matches);
1536
1703
  throw new WikiGraphArchiveOwnershipError(
@@ -1539,15 +1706,26 @@ async function assertStandaloneWikiGraphArchivePath(inputPath) {
1539
1706
  )}: ${path}. Use the library UUID URI ${match.archive.uri} instead.`
1540
1707
  );
1541
1708
  }
1542
- for (const library of libraries) {
1543
- const rootPath = getNodeResourcePath(library.folder);
1544
- const root = await canonicalPath(rootPath);
1545
- if (!isWithin(root, candidate)) continue;
1546
- throw new WikiGraphArchiveOwnershipError(
1547
- `Standalone archive path belongs to registered library ${(0, import_wiki_graph_core2.formatWikiGraphLibraryUri)(
1548
- library.isDefault ? void 0 : library.publicId
1549
- )}: ${path}. Scan the library, then address the archive by its library UUID URI.`
1709
+ const ancestors = /* @__PURE__ */ new Set();
1710
+ for (const start of [candidate, (0, import_path3.resolve)(path)]) {
1711
+ for (let parent = (0, import_path3.dirname)(start); ; parent = (0, import_path3.dirname)(parent)) {
1712
+ ancestors.add(parent);
1713
+ if ((0, import_path3.dirname)(parent) === parent) break;
1714
+ }
1715
+ }
1716
+ for (const parent of ancestors) {
1717
+ const identity = await readFileIdentity(parent);
1718
+ const library = await (0, import_wiki_graph_core2.findWikiGraphLibraryByPhysicalIdentity)(
1719
+ identity,
1720
+ new NodeDirectory(parent).identity
1550
1721
  );
1722
+ if (library !== void 0) {
1723
+ throw new WikiGraphArchiveOwnershipError(
1724
+ `Standalone archive path belongs to registered library ${(0, import_wiki_graph_core2.formatWikiGraphLibraryUri)(
1725
+ library.isDefault ? void 0 : library.publicId
1726
+ )}: ${path}. Scan the library, then address the archive by its library UUID URI.`
1727
+ );
1728
+ }
1551
1729
  }
1552
1730
  return path;
1553
1731
  }
@@ -1565,11 +1743,7 @@ async function resolveWikiGraphArchiveTarget(file) {
1565
1743
  const path = getNodeResourcePath(file);
1566
1744
  const candidate = await canonicalPath(path);
1567
1745
  const candidateIdentity = await readFileIdentity(path);
1568
- const matches = await findMatchingMembers(
1569
- await (0, import_wiki_graph_core2.listWikiGraphLibraries)(),
1570
- candidate,
1571
- candidateIdentity
1572
- );
1746
+ const matches = await findMatchingMembers(candidate, candidateIdentity);
1573
1747
  if (matches.length > 0) {
1574
1748
  const match = requireUnambiguousManagedMatch(path, matches);
1575
1749
  return { kind: "library", uri: match.archive.uri };
@@ -1635,48 +1809,35 @@ function withObjectUri(archiveLocator, objectUri) {
1635
1809
  async function canonicalPath(path) {
1636
1810
  try {
1637
1811
  return await (0, import_promises3.realpath)(path);
1638
- } catch {
1812
+ } catch (error) {
1813
+ if (!(typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR")))
1814
+ throw error;
1639
1815
  const absolute = (0, import_path3.resolve)(path);
1640
1816
  const parent = (0, import_path3.dirname)(absolute);
1641
1817
  return parent === absolute ? absolute : (0, import_path3.join)(await canonicalPath(parent), (0, import_path3.basename)(absolute));
1642
1818
  }
1643
1819
  }
1644
- function isWithin(root, candidate) {
1645
- const child = (0, import_path3.relative)(root, candidate);
1646
- return child === "" || !child.startsWith("..") && !(0, import_path3.isAbsolute)(child);
1647
- }
1648
- async function findMatchingMembers(libraries, candidate, candidateIdentity) {
1820
+ async function findMatchingMembers(candidate, candidateIdentity) {
1821
+ if (candidateIdentity === void 0) return [];
1822
+ const archives = await (0, import_wiki_graph_core2.findWikiGraphLibraryArchivePhysicalAliases)(candidateIdentity);
1649
1823
  const members = [];
1650
- for (const library of libraries) {
1651
- const archives = await (0, import_wiki_graph_core2.listWikiGraphLibraryArchives)({
1652
- isDefault: library.isDefault,
1653
- kind: "scope",
1654
- ...library.isDefault ? {} : { publicId: library.publicId }
1655
- });
1656
- for (const archive of archives) {
1657
- const physical = archive.file ?? archive.directory;
1658
- if (physical === void 0) continue;
1824
+ for (const archive of archives) {
1825
+ const parsed = (0, import_wiki_graph_core2.parseWikiGraphLibraryUri)(archive.libraryUri);
1826
+ const library = await (0, import_wiki_graph_core2.resolveWikiGraphLibrary)(parsed);
1827
+ const physical = archive.file ?? archive.directory;
1828
+ if (library !== void 0 && physical !== void 0)
1659
1829
  members.push({
1660
1830
  archive,
1661
1831
  library,
1662
1832
  memberPath: getNodeResourcePath(physical)
1663
1833
  });
1664
- }
1665
1834
  }
1666
1835
  const exact = [];
1667
1836
  for (const member of members) {
1668
- if (await canonicalPath(member.memberPath) === candidate) {
1837
+ if (await canonicalPath(member.memberPath) === candidate)
1669
1838
  exact.push(member);
1670
- }
1671
- }
1672
- if (exact.length > 0 || candidateIdentity === void 0) return exact;
1673
- const identityMatches = [];
1674
- for (const member of members) {
1675
- if (await readFileIdentity(member.memberPath) === candidateIdentity) {
1676
- identityMatches.push(member);
1677
- }
1678
1839
  }
1679
- return identityMatches;
1840
+ return exact.length > 0 ? exact : members;
1680
1841
  }
1681
1842
  function requireUnambiguousManagedMatch(path, matches) {
1682
1843
  if (matches.length === 1) return matches[0];
@@ -1688,8 +1849,10 @@ async function readFileIdentity(path) {
1688
1849
  try {
1689
1850
  const value = await (0, import_promises3.stat)(path);
1690
1851
  return `${value.dev}:${value.ino}`;
1691
- } catch {
1692
- return void 0;
1852
+ } catch (error) {
1853
+ if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
1854
+ return void 0;
1855
+ throw error;
1693
1856
  }
1694
1857
  }
1695
1858
 
@@ -1751,11 +1914,15 @@ var WikiGraphConversionManager = class {
1751
1914
  if (!("path" in options.input)) {
1752
1915
  throw new Error("wikg input requires a file path.");
1753
1916
  }
1917
+ const inputPath = options.input.path;
1754
1918
  await app.openSession(
1755
- new NodeFile(
1756
- await assertStandaloneWikiGraphArchivePath(options.input.path)
1757
- ),
1919
+ new NodeFile(await assertStandaloneWikiGraphArchivePath(inputPath)),
1758
1920
  write
1921
+ ).catch(
1922
+ (error) => rethrowArchiveSchemaError(error, {
1923
+ kind: "standalone",
1924
+ path: inputPath
1925
+ })
1759
1926
  );
1760
1927
  } else if ("stream" in options.input) {
1761
1928
  await app.digestTextStreamSession(
@@ -2171,6 +2338,12 @@ var import_wiki_graph_core6 = require("wiki-graph-core");
2171
2338
  async function writeWikiGraphArchiveLocation(location, operation, options = {}) {
2172
2339
  const cacheOnly = options.searchIndexWritebackPolicy === "cache";
2173
2340
  const write = async (archiveFile = location.archiveFile) => {
2341
+ if (cacheOnly) {
2342
+ return await new import_wiki_graph_core6.WikiGraphArchiveFile(archiveFile).readDocument(
2343
+ operation,
2344
+ { searchIndexWritebackPolicy: "cache" }
2345
+ );
2346
+ }
2174
2347
  const writeOptions = {
2175
2348
  ...cacheOnly ? {} : { derivedStateKeys: [location.archiveKey, location.archivePath] },
2176
2349
  ...options.invalidateContinuationCursors === void 0 ? {} : {
@@ -2546,10 +2719,15 @@ var WikiGraphArchiveManager = class {
2546
2719
  }, options.signal);
2547
2720
  }
2548
2721
  async open(target, options = {}) {
2549
- const location = await this.#runtime.run(
2550
- async () => await resolveWikiGraphArchiveLocation(target),
2551
- options.signal
2552
- );
2722
+ const location = await this.#runtime.run(async () => {
2723
+ const location2 = await resolveWikiGraphArchiveLocation(target);
2724
+ try {
2725
+ await (0, import_wiki_graph_core7.ensureWikiGraphArchiveSchemaCurrent)(location2.archiveFile);
2726
+ } catch (error) {
2727
+ rethrowArchiveSchemaError(error, target);
2728
+ }
2729
+ return location2;
2730
+ }, options.signal);
2553
2731
  return new WikiGraphArchiveHandle(this.#runtime, location);
2554
2732
  }
2555
2733
  };
@@ -2600,15 +2778,11 @@ var WikiGraphArchiveHandle = class {
2600
2778
  options.queryMode,
2601
2779
  options.signal
2602
2780
  );
2603
- const result = await this.#writeDocument(
2781
+ const result = await this.#readDocument(
2604
2782
  async (document) => {
2605
2783
  const chapters = await this.#resolveQueryChapters(document, options, {
2606
2784
  embeddingProvider
2607
2785
  });
2608
- await ensureArchiveSearchIndex(document, {
2609
- ...chapters === void 0 ? {} : { chapters },
2610
- ...embeddingProvider === void 0 ? {} : { embeddingProvider }
2611
- });
2612
2786
  return await (0, import_wiki_graph_core7.findArchiveObjects)(document, query, {
2613
2787
  ...withoutOperationAndScope(options),
2614
2788
  archiveKey: this.archiveKey,
@@ -2617,7 +2791,6 @@ var WikiGraphArchiveHandle = class {
2617
2791
  });
2618
2792
  },
2619
2793
  {
2620
- searchIndexWritebackPolicy: "cache",
2621
2794
  ...options.signal === void 0 ? {} : { signal: options.signal }
2622
2795
  }
2623
2796
  );
@@ -2722,6 +2895,7 @@ var WikiGraphArchiveHandle = class {
2722
2895
  async (document) => {
2723
2896
  const chapters = await this.#resolveScope(document, options);
2724
2897
  await ensureArchiveSearchIndex(document, {
2898
+ rebuild: true,
2725
2899
  ...chapters === void 0 ? {} : { chapters },
2726
2900
  ...embeddingProvider === void 0 ? {} : { embeddingProvider }
2727
2901
  });
@@ -2972,13 +3146,16 @@ var WikiGraphArchiveHandle = class {
2972
3146
  return await this.#runtime.run(
2973
3147
  async () => await withConfiguredWikimediaResolver(
2974
3148
  objectUri,
2975
- async (wikimediaOptions) => await this.#readDocument(
2976
- async (document) => await (0, import_wiki_graph_core7.readArchivePage)(document, objectUri, {
2977
- ...options,
2978
- ...wikimediaOptions
2979
- }),
2980
- options
2981
- )
3149
+ async (wikimediaOptions) => {
3150
+ const read2 = await this.#readDocument(
3151
+ async (document) => await (0, import_wiki_graph_core7.prepareArchivePage)(document, objectUri, {
3152
+ ...options,
3153
+ ...wikimediaOptions
3154
+ }),
3155
+ options
3156
+ );
3157
+ return await read2();
3158
+ }
2982
3159
  ),
2983
3160
  options.signal
2984
3161
  );
@@ -3011,15 +3188,11 @@ var WikiGraphArchiveHandle = class {
3011
3188
  options.queryMode,
3012
3189
  options.signal
3013
3190
  );
3014
- const result = await this.#writeDocument(
3191
+ const result = await this.#readDocument(
3015
3192
  async (document) => {
3016
3193
  const chapters = await this.#resolveQueryChapters(document, options, {
3017
3194
  embeddingProvider
3018
3195
  });
3019
- await ensureArchiveSearchIndex(document, {
3020
- ...chapters === void 0 ? {} : { chapters },
3021
- ...embeddingProvider === void 0 ? {} : { embeddingProvider }
3022
- });
3023
3196
  return await (0, import_wiki_graph_core7.listRelatedArchiveObjects)(document, objectUri, {
3024
3197
  ...withoutOperation(options),
3025
3198
  ...embeddingProvider === void 0 ? {} : { embeddingProvider },
@@ -3027,7 +3200,6 @@ var WikiGraphArchiveHandle = class {
3027
3200
  });
3028
3201
  },
3029
3202
  {
3030
- searchIndexWritebackPolicy: "cache",
3031
3203
  ...options.signal === void 0 ? {} : { signal: options.signal }
3032
3204
  }
3033
3205
  );
@@ -3071,15 +3243,11 @@ var WikiGraphArchiveHandle = class {
3071
3243
  options.queryMode,
3072
3244
  options.signal
3073
3245
  );
3074
- const result = await this.#writeDocument(
3246
+ const result = await this.#readDocument(
3075
3247
  async (document) => {
3076
3248
  const chapters = await this.#resolveQueryChapters(document, options, {
3077
3249
  embeddingProvider
3078
3250
  });
3079
- await ensureArchiveSearchIndex(document, {
3080
- ...chapters === void 0 ? {} : { chapters },
3081
- ...embeddingProvider === void 0 ? {} : { embeddingProvider }
3082
- });
3083
3251
  return await (0, import_wiki_graph_core7.listArchiveEvidence)(document, objectUri, {
3084
3252
  ...withoutOperation(options),
3085
3253
  ...embeddingProvider === void 0 ? {} : { embeddingProvider },
@@ -3087,7 +3255,6 @@ var WikiGraphArchiveHandle = class {
3087
3255
  });
3088
3256
  },
3089
3257
  {
3090
- searchIndexWritebackPolicy: "cache",
3091
3258
  ...options.signal === void 0 ? {} : { signal: options.signal }
3092
3259
  }
3093
3260
  );
@@ -3204,6 +3371,8 @@ var WikiGraphArchiveHandle = class {
3204
3371
  this.#location.archiveFile
3205
3372
  ).readDocument(operation),
3206
3373
  options.signal
3374
+ ).catch(
3375
+ (error) => rethrowArchiveSchemaError(error, this.#location.target)
3207
3376
  );
3208
3377
  }
3209
3378
  async #writeDocument(operation, options = {}) {
@@ -3215,33 +3384,32 @@ var WikiGraphArchiveHandle = class {
3215
3384
  searchIndexWritebackPolicy: options.searchIndexWritebackPolicy
3216
3385
  }
3217
3386
  });
3218
- }, options.signal);
3387
+ }, options.signal).catch(
3388
+ (error) => rethrowArchiveSchemaError(error, this.#location.target)
3389
+ );
3219
3390
  }
3220
3391
  async #resolveScope(document, options) {
3221
3392
  if (options.chapters !== void 0) return options.chapters;
3222
3393
  return (await resolveArchiveScope(document, this.objectUri, options.depth))?.chapterIds;
3223
3394
  }
3224
3395
  async #resolveQueryChapters(document, options, capabilities) {
3225
- const chapters = await this.#resolveScope(document, options);
3396
+ const parsed = parseChapterScopePath(this.objectUri);
3397
+ const chapters = options.chapters ?? (parsed === void 0 || parsed.kind === "collection" && options.depth === void 0 ? void 0 : await (0, import_wiki_graph_core7.resolveIndexedArchiveChapterScope)(
3398
+ document,
3399
+ parsed.kind === "chapter" ? parsed.chapterPath : void 0,
3400
+ options.depth
3401
+ ));
3226
3402
  const coverageOptions = {
3227
3403
  ...chapters === void 0 ? {} : { chapters },
3228
3404
  ...capabilities.embeddingProvider === void 0 ? {} : { embeddingProvider: capabilities.embeddingProvider },
3229
3405
  requireEmbeddingProvider: true,
3230
3406
  ...options.queryMode === void 0 ? {} : { queryMode: options.queryMode }
3231
3407
  };
3232
- if (options.skipUnindexed !== true) {
3233
- await (0, import_wiki_graph_core7.assertArchiveIndexArtifactsReady)(document, coverageOptions);
3234
- return chapters;
3235
- }
3236
- const queryable = await (0, import_wiki_graph_core7.listArchiveQueryableChapterIds)(document, {
3237
- ...coverageOptions
3408
+ await (0, import_wiki_graph_core7.assertArchiveQueryReady)(document, {
3409
+ ...coverageOptions,
3410
+ ...options.skipUnindexed === void 0 ? {} : { skipUnindexed: options.skipUnindexed }
3238
3411
  });
3239
- if (queryable.length === 0) {
3240
- throw new Error(
3241
- "Wiki Graph query is not ready. No chapters in this scope have a current FTS artifact or source embedding artifact."
3242
- );
3243
- }
3244
- return queryable;
3412
+ return chapters;
3245
3413
  }
3246
3414
  async #resolveQueryEmbeddingProvider(queryMode, signal) {
3247
3415
  if (queryMode === "fts") return void 0;
@@ -3260,6 +3428,10 @@ var WikiGraphArchiveHandle = class {
3260
3428
  async function ensureArchiveSearchIndex(document, options = {}) {
3261
3429
  const scope = options.chapters === void 0 ? {} : { chapters: options.chapters };
3262
3430
  if (await (0, import_wiki_graph_core7.isArchiveSearchIndexCurrent)(document, scope)) return;
3431
+ if (options.rebuild !== true)
3432
+ throw new Error(
3433
+ "Archive search index is missing or dirty. Run `wg <archive-uri>/index sync` explicitly before querying."
3434
+ );
3263
3435
  await (0, import_wiki_graph_core7.rebuildArchiveSearchIndex)(document, void 0, {
3264
3436
  ...scope,
3265
3437
  ...options.embeddingProvider === void 0 ? {} : { embeddingProvider: options.embeddingProvider }
@@ -3639,7 +3811,7 @@ async function continueArchiveCursor(cursor, limit) {
3639
3811
  const location = await resolveWikiGraphArchiveLocation(
3640
3812
  archiveTargetFromLogicalLocator(getCursorArchivePath(cursor))
3641
3813
  );
3642
- const read = async (document) => {
3814
+ const read2 = async (document) => {
3643
3815
  switch (cursor.kind) {
3644
3816
  case "source-locators":
3645
3817
  return await (0, import_wiki_graph_core9.listArchiveSourceLocators)(document, cursor.targetUri, {
@@ -3685,7 +3857,9 @@ async function continueArchiveCursor(cursor, limit) {
3685
3857
  });
3686
3858
  }
3687
3859
  };
3688
- return location.archiveFile.kind === "directory" ? await new import_wiki_graph_core9.WikiGraphDirectoryFile(location.archiveFile).readDocument(read) : await new import_wiki_graph_core9.WikiGraphArchiveFile(location.archiveFile).readDocument(read);
3860
+ return await (location.archiveFile.kind === "directory" ? new import_wiki_graph_core9.WikiGraphDirectoryFile(location.archiveFile).readDocument(read2) : new import_wiki_graph_core9.WikiGraphArchiveFile(location.archiveFile).readDocument(read2)).catch(
3861
+ (error) => rethrowArchiveSchemaError(error, location.target)
3862
+ );
3689
3863
  }
3690
3864
  async function continueLibraryCursor(cursor, limit) {
3691
3865
  const embeddingProvider = cursor.kind === "evidence" || cursor.kind === "related" ? await resolveCursorEmbeddingProvider(cursor) : void 0;
@@ -4971,8 +5145,7 @@ async function readQueueReadinessReason(document, chapter, target) {
4971
5145
  return "planned";
4972
5146
  }
4973
5147
  if (target === "index-embedding-summary") {
4974
- const summary = await document.readSummary(chapter.chapterId);
4975
- if (summary === void 0 || summary.trim() === "") {
5148
+ if (chapter.stage !== "summarized") {
4976
5149
  return "missing summary";
4977
5150
  }
4978
5151
  }
@@ -5124,20 +5297,27 @@ var WikiGraphLibraryManager = class {
5124
5297
  throwIfAborted(options.signal);
5125
5298
  const archive = await (0, import_wiki_graph_core16.getWikiGraphLibraryArchive)(parsedTarget);
5126
5299
  const source = requireReadableLibraryArchiveFile(archive);
5300
+ await (0, import_wiki_graph_core16.ensureWikiGraphArchiveSchemaCurrent)(source).catch(
5301
+ (error) => rethrowArchiveSchemaError(error, {
5302
+ kind: "library",
5303
+ uri: archive.uri
5304
+ })
5305
+ );
5127
5306
  let temporaryDirectory;
5128
- const file = source.kind === "directory" ? await (async () => {
5129
- temporaryDirectory = await (0, import_promises6.mkdtemp)(
5130
- (0, import_path6.join)((0, import_os4.tmpdir)(), "wikigraph-library-read-")
5131
- );
5132
- const output = new NodeFile(
5133
- (0, import_path6.join)(temporaryDirectory, "archive.wikg")
5134
- );
5135
- await (0, import_wiki_graph_core16.writeWikgArchive)(source, output);
5136
- return output;
5137
- })() : source;
5138
- const reader = await file.openReader();
5307
+ let reader;
5139
5308
  let active = true;
5140
5309
  try {
5310
+ const file = source.kind === "directory" ? await (async () => {
5311
+ temporaryDirectory = await (0, import_promises6.mkdtemp)(
5312
+ (0, import_path6.join)((0, import_os4.tmpdir)(), "wikigraph-library-read-")
5313
+ );
5314
+ const output = new NodeFile(
5315
+ (0, import_path6.join)(temporaryDirectory, "archive.wikg")
5316
+ );
5317
+ await (0, import_wiki_graph_core16.writeWikgArchive)(source, output);
5318
+ return output;
5319
+ })() : source;
5320
+ reader = await file.openReader();
5141
5321
  const content = {
5142
5322
  mediaType: "application/vnd.wiki-graph.archive",
5143
5323
  size: reader.size,
@@ -5154,9 +5334,12 @@ var WikiGraphLibraryManager = class {
5154
5334
  );
5155
5335
  } finally {
5156
5336
  active = false;
5157
- await reader.close();
5158
- if (temporaryDirectory !== void 0)
5159
- await (0, import_promises6.rm)(temporaryDirectory, { force: true, recursive: true });
5337
+ try {
5338
+ await reader?.close();
5339
+ } finally {
5340
+ if (temporaryDirectory !== void 0)
5341
+ await (0, import_promises6.rm)(temporaryDirectory, { force: true, recursive: true });
5342
+ }
5160
5343
  }
5161
5344
  },
5162
5345
  options.signal === void 0 ? {} : { signal: options.signal }
@@ -5657,7 +5840,9 @@ var WikiGraphMaintenanceManager = class {
5657
5840
  return await (0, import_wiki_graph_core17.upgradeWikiGraphMaintenanceTarget)({
5658
5841
  file: new NodeFile(path),
5659
5842
  kind: "archive"
5660
- });
5843
+ }).catch(
5844
+ (error) => rethrowArchiveSchemaError(error, { kind: "standalone", path })
5845
+ );
5661
5846
  },
5662
5847
  void 0,
5663
5848
  { skipHomeBootstrap: target.kind === "home" }
@@ -5686,7 +5871,6 @@ function defaultWikgOutputPath(inputPath) {
5686
5871
  var import_wiki_graph_core18 = require("wiki-graph-core");
5687
5872
  var WikiGraphSDK = class {
5688
5873
  #context;
5689
- #homeReady;
5690
5874
  archives;
5691
5875
  conversions;
5692
5876
  config;
@@ -5717,13 +5901,7 @@ var WikiGraphSDK = class {
5717
5901
  throwIfAborted2(signal);
5718
5902
  const runWithContext = async () => await withWikiGraphSDKRuntimeContext(this.#context, async () => {
5719
5903
  if (options.skipHomeBootstrap !== true) {
5720
- this.#homeReady ??= (0, import_wiki_graph_core18.ensureWikiGraphHomeSchemaCurrent)().catch(
5721
- (error) => {
5722
- this.#homeReady = void 0;
5723
- throw error;
5724
- }
5725
- );
5726
- await this.#homeReady;
5904
+ await (0, import_wiki_graph_core18.ensureWikiGraphHomeSchemaCurrent)();
5727
5905
  }
5728
5906
  return await operation();
5729
5907
  });
@@ -5783,6 +5961,7 @@ var import_wiki_graph_core19 = require("wiki-graph-core");
5783
5961
  WikiGraphLibraryManager,
5784
5962
  WikiGraphMaintenanceManager,
5785
5963
  WikiGraphSDK,
5964
+ WikiGraphSchemaVersionError,
5786
5965
  buildSearchIndexEmbeddingProvider,
5787
5966
  buildWikiGraphLLMOptions,
5788
5967
  clearLocalConfigSection,
@@ -5825,6 +6004,7 @@ var import_wiki_graph_core19 = require("wiki-graph-core");
5825
6004
  isSourceLocatorScopeUri,
5826
6005
  isWikiGraphJobUri,
5827
6006
  isWikiGraphLibraryUri,
6007
+ isWikiGraphSchemaVersionError,
5828
6008
  isWikiGraphUri,
5829
6009
  iterateItems,
5830
6010
  iteratePages,