kibi-runtime 2.9.0 → 2.11.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.
@@ -4,7 +4,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
4
4
 
5
5
  // ../cli/src/engine-daemon.ts
6
6
  import { writeFileSync as writeFileSync3 } from "node:fs";
7
- import path8 from "node:path";
7
+ import path9 from "node:path";
8
8
  import { pathToFileURL } from "node:url";
9
9
 
10
10
  // ../cli/src/engine.ts
@@ -17,7 +17,7 @@ import {
17
17
  lstatSync as lstatSync3,
18
18
  mkdirSync as mkdirSync2,
19
19
  openSync as openSync2,
20
- readFileSync as readFileSync4,
20
+ readFileSync as readFileSync5,
21
21
  readdirSync as readdirSync2,
22
22
  realpathSync as realpathSync3,
23
23
  renameSync,
@@ -28,7 +28,7 @@ import {
28
28
  } from "node:fs";
29
29
  import * as net from "node:net";
30
30
  import * as os from "node:os";
31
- import * as path7 from "node:path";
31
+ import * as path8 from "node:path";
32
32
  import { performance as performance2 } from "node:perf_hooks";
33
33
 
34
34
  // ../cli/src/engine-limits.ts
@@ -85,6 +85,40 @@ function queryLimitMessage(hit) {
85
85
  return `${QUERY_LIMIT_EXCEEDED_CODE}: read stopped at its ${budget} before computing an answer. Narrow the query or raise the limit.`;
86
86
  }
87
87
 
88
+ // ../cli/src/package-versions.ts
89
+ import { readFileSync } from "node:fs";
90
+ import { createRequire as createRequire2 } from "node:module";
91
+ import path from "node:path";
92
+ import { fileURLToPath } from "node:url";
93
+ var require2 = createRequire2(import.meta.url);
94
+ var moduleDirectory = path.dirname(fileURLToPath(import.meta.url));
95
+ function manifestVersion(manifestPath, expectedName) {
96
+ try {
97
+ const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
98
+ return manifest.name === expectedName && typeof manifest.version === "string" ? manifest.version : undefined;
99
+ } catch {
100
+ return;
101
+ }
102
+ }
103
+ function cliVersion() {
104
+ if (true)
105
+ return "2.13.0";
106
+ return manifestVersion(path.join(moduleDirectory, "..", "package.json"), "kibi-cli") ?? "unknown";
107
+ }
108
+ function coreVersion() {
109
+ try {
110
+ const resolved = manifestVersion(require2.resolve("kibi-core/package.json"), "kibi-core");
111
+ if (resolved)
112
+ return resolved;
113
+ } catch {}
114
+ return manifestVersion(path.join(moduleDirectory, "..", "..", "core", "package.json"), "kibi-core") ?? "unknown";
115
+ }
116
+ var KIBI_BUILT_PACKAGE_VERSIONS = `kibi-cli@${cliVersion()},kibi-core@${coreVersion()}`;
117
+ function kibiPackageVersions() {
118
+ const override = process.env.KIBI_PACKAGE_VERSIONS;
119
+ return override !== undefined && override.length > 0 ? override : KIBI_BUILT_PACKAGE_VERSIONS;
120
+ }
121
+
88
122
  // ../cli/src/performance-trace.ts
89
123
  import { constants } from "node:fs";
90
124
  import {
@@ -96,7 +130,7 @@ import {
96
130
  statSync,
97
131
  writeSync
98
132
  } from "node:fs";
99
- import path from "node:path";
133
+ import path2 from "node:path";
100
134
  var KIBI_PERF_TRACE_DIR_ENV = "KIBI_PERF_TRACE_DIR";
101
135
  var KIBI_PERF_TIMINGS_ENV = "KIBI_PERF_TIMINGS";
102
136
  var KIBI_PERF_TRACE_MAX_EVENTS = 5000;
@@ -105,14 +139,14 @@ var states = new Map;
105
139
  var MAX_DURATION_MS = 60000;
106
140
  var TRACE_LIMIT_RESERVE_BYTES = 96;
107
141
  function isWithin(parent, candidate) {
108
- const relative = path.relative(parent, candidate);
109
- return relative === "" || relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
142
+ const relative = path2.relative(parent, candidate);
143
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path2.sep}`) && !path2.isAbsolute(relative);
110
144
  }
111
145
  function privateTraceFile() {
112
146
  if (process.env[KIBI_PERF_TIMINGS_ENV] !== "1")
113
147
  return null;
114
148
  const configuredDirectory = process.env[KIBI_PERF_TRACE_DIR_ENV];
115
- if (!configuredDirectory || !path.isAbsolute(configuredDirectory))
149
+ if (!configuredDirectory || !path2.isAbsolute(configuredDirectory))
116
150
  return null;
117
151
  try {
118
152
  const directoryInfo = lstatSync(configuredDirectory);
@@ -120,7 +154,7 @@ function privateTraceFile() {
120
154
  return null;
121
155
  }
122
156
  const directory = realpathSync(configuredDirectory);
123
- if (path.resolve(configuredDirectory) !== directory)
157
+ if (path2.resolve(configuredDirectory) !== directory)
124
158
  return null;
125
159
  const directoryStats = statSync(directory);
126
160
  if (typeof process.getuid !== "function" || directoryStats.uid !== process.getuid()) {
@@ -132,7 +166,7 @@ function privateTraceFile() {
132
166
  const currentDirectory = realpathSync(process.cwd());
133
167
  if (isWithin(currentDirectory, directory))
134
168
  return null;
135
- const file = path.join(directory, `kibi-performance-${process.pid}.jsonl`);
169
+ const file = path2.join(directory, `kibi-performance-${process.pid}.jsonl`);
136
170
  let state = states.get(file);
137
171
  if (!state) {
138
172
  if (existsSync(file))
@@ -210,10 +244,10 @@ function writePerformanceTraceEvent(event) {
210
244
  // ../cli/src/prolog.ts
211
245
  import { spawn } from "node:child_process";
212
246
  import { existsSync as existsSync3 } from "node:fs";
213
- import { createRequire as createRequire2 } from "node:module";
214
- import path3 from "node:path";
247
+ import { createRequire as createRequire3 } from "node:module";
248
+ import path4 from "node:path";
215
249
  import { performance } from "node:perf_hooks";
216
- import { fileURLToPath } from "node:url";
250
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
217
251
 
218
252
  // ../cli/src/env.ts
219
253
  function getEnvValue(key) {
@@ -568,10 +602,10 @@ import {
568
602
  constants as constants2,
569
603
  accessSync,
570
604
  existsSync as existsSync2,
571
- readFileSync,
605
+ readFileSync as readFileSync2,
572
606
  statSync as statSync2
573
607
  } from "node:fs";
574
- import path2 from "node:path";
608
+ import path3 from "node:path";
575
609
  import {
576
610
  BUNDLED_BINARY_PATH,
577
611
  MANIFEST_FILE,
@@ -666,8 +700,8 @@ function inspectBundle(deps) {
666
700
  const packageDir = deps.locatePackage(packageName);
667
701
  if (packageDir === undefined)
668
702
  return { kind: "missing", key, packageName };
669
- const manifestPath = path2.join(packageDir, MANIFEST_FILE);
670
- const binary = path2.join(packageDir, BUNDLED_BINARY_PATH);
703
+ const manifestPath = path3.join(packageDir, MANIFEST_FILE);
704
+ const binary = path3.join(packageDir, BUNDLED_BINARY_PATH);
671
705
  if (!existsSync2(manifestPath)) {
672
706
  if (!existsSync2(binary))
673
707
  return { kind: "empty", key, packageName };
@@ -687,12 +721,12 @@ function inspectBundle(deps) {
687
721
  let manifest;
688
722
  let packageJson;
689
723
  try {
690
- manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
724
+ manifest = JSON.parse(readFileSync2(manifestPath, "utf8"));
691
725
  } catch (error) {
692
726
  return corrupt(`${MANIFEST_FILE} is not valid JSON (${error instanceof Error ? error.message : String(error)})`);
693
727
  }
694
728
  try {
695
- packageJson = JSON.parse(readFileSync(path2.join(packageDir, "package.json"), "utf8"));
729
+ packageJson = JSON.parse(readFileSync2(path3.join(packageDir, "package.json"), "utf8"));
696
730
  } catch (error) {
697
731
  return corrupt(`package.json is unreadable (${error instanceof Error ? error.message : String(error)})`);
698
732
  }
@@ -715,7 +749,7 @@ function inspectBundle(deps) {
715
749
  if (actual !== checked.binarySha256) {
716
750
  return corrupt(`${BUNDLED_BINARY_PATH} SHA-256 ${actual} does not match the manifest (${checked.binarySha256})`);
717
751
  }
718
- const home = path2.join(packageDir, checked.home);
752
+ const home = path3.join(packageDir, checked.home);
719
753
  let homeIsDirectory = false;
720
754
  try {
721
755
  homeIsDirectory = statSync2(home).isDirectory();
@@ -757,10 +791,10 @@ function probeVersion(bin, deps) {
757
791
  return { kind: "ok", version: parsed.version };
758
792
  }
759
793
  function findOnPath(env, deps) {
760
- for (const directory of (env.PATH ?? "").split(path2.delimiter)) {
761
- if (directory === "" || !path2.isAbsolute(directory))
794
+ for (const directory of (env.PATH ?? "").split(path3.delimiter)) {
795
+ if (directory === "" || !path3.isAbsolute(directory))
762
796
  continue;
763
- const candidate = path2.join(directory, "swipl");
797
+ const candidate = path3.join(directory, "swipl");
764
798
  if (!isExecutableFile(candidate))
765
799
  continue;
766
800
  const probe = probeVersion(candidate, deps);
@@ -783,7 +817,7 @@ function resolveFromEnv(override, deps) {
783
817
  });
784
818
  const packageName = key === undefined ? undefined : PLATFORM_PACKAGES[key].package;
785
819
  const invalid = (detail) => new SwiplResolutionError("swipl_env_invalid", `KIBI_SWIPL=${override} ${detail}. Set KIBI_SWIPL to the absolute path of a SWI-Prolog ${MINIMUM_SWIPL_MAJOR}.0+ executable, to "system" to use swipl from PATH, or unset it to use the bundled runtime.`, platform, packageName);
786
- if (!path2.isAbsolute(override))
820
+ if (!path3.isAbsolute(override))
787
821
  return fail(invalid("is not an absolute path"));
788
822
  if (!isExecutableFile(override)) {
789
823
  return fail(invalid("is not an executable file"));
@@ -891,24 +925,11 @@ function swiplChildEnv(resolved) {
891
925
  }
892
926
 
893
927
  // ../cli/src/prolog.ts
894
- var importMetaDir = path3.dirname(fileURLToPath(import.meta.url));
928
+ var importMetaDir = path4.dirname(fileURLToPath2(import.meta.url));
895
929
  var DEFAULT_PROLOG_OUTPUT_MAX_BUFFER_BYTES = 8 * 1024 * 1024;
896
930
  var PROLOG_OUTPUT_OVERFLOW_ERROR = "Query exceeded bounded Prolog output capacity (ENOBUFS); narrow the operation or reduce stored entity size";
897
931
  var INTERACTIVE_QUERY_FRAME_END = "__KIBI_QUERY_FRAME_END__";
898
- var require2 = createRequire2(import.meta.url);
899
- function packageVersion(packagePath) {
900
- try {
901
- const packageJson = require2(packagePath);
902
- return typeof packageJson.version === "string" ? packageJson.version : "unknown";
903
- } catch {
904
- return "unknown";
905
- }
906
- }
907
- var KIBI_PACKAGE_VERSIONS = [
908
- `kibi-cli@${packageVersion(path3.join(importMetaDir, "..", "package.json"))}`,
909
- `kibi-core@${packageVersion(path3.join(importMetaDir, "..", "..", "core", "package.json"))}`,
910
- `kibi-mcp@${packageVersion(path3.join(importMetaDir, "..", "..", "mcp", "package.json"))}`
911
- ].join(",");
932
+ var require3 = createRequire3(import.meta.url);
912
933
  function resolveKbPlPath() {
913
934
  const overrideKbPath = getKbPlPathOverride();
914
935
  if (overrideKbPath) {
@@ -916,20 +937,20 @@ function resolveKbPlPath() {
916
937
  }
917
938
  try {
918
939
  try {
919
- return require2.resolve("kibi-core/src/kb.pl");
940
+ return require3.resolve("kibi-core/src/kb.pl");
920
941
  } catch {
921
- const coreMain = require2.resolve("kibi-core");
922
- const coreDir = path3.dirname(coreMain);
923
- return path3.join(coreDir, "src", "kb.pl");
942
+ const coreMain = require3.resolve("kibi-core");
943
+ const coreDir = path4.dirname(coreMain);
944
+ return path4.join(coreDir, "src", "kb.pl");
924
945
  }
925
946
  } catch {}
926
947
  let currentDir = importMetaDir;
927
- while (currentDir !== path3.dirname(currentDir)) {
928
- const candidate = path3.join(currentDir, "packages", "core", "src", "kb.pl");
948
+ while (currentDir !== path4.dirname(currentDir)) {
949
+ const candidate = path4.join(currentDir, "packages", "core", "src", "kb.pl");
929
950
  if (existsSync3(candidate)) {
930
951
  return candidate;
931
952
  }
932
- currentDir = path3.dirname(currentDir);
953
+ currentDir = path4.dirname(currentDir);
933
954
  }
934
955
  throw new Error("Unable to resolve kb.pl. Expected kibi-core to be installed (node_modules) " + "or to be running inside the monorepo checkout.");
935
956
  }
@@ -1021,7 +1042,7 @@ class PrologProcess {
1021
1042
  ...launch.env,
1022
1043
  KIBI_RUNTIME_NAME: process.versions.bun !== undefined ? "bun" : "node",
1023
1044
  KIBI_RUNTIME_VERSION: process.versions.bun ?? process.versions.node ?? "unknown",
1024
- KIBI_PACKAGE_VERSIONS: process.env.KIBI_PACKAGE_VERSIONS ?? KIBI_PACKAGE_VERSIONS
1045
+ KIBI_PACKAGE_VERSIONS: kibiPackageVersions()
1025
1046
  }
1026
1047
  });
1027
1048
  this.clearQueryBuffers();
@@ -1142,7 +1163,7 @@ writeln('${INTERACTIVE_QUERY_FRAME_END}').
1142
1163
  console.error(`[prolog debug] timeout: ${msg}`);
1143
1164
  const runtime = this.errorBuffer.split(`
1144
1165
  `).find((line) => line.includes("__KIBI_RUNTIME__"));
1145
- console.error(`[prolog debug] runtime=${runtime ?? "unknown"} packages=${process.env.KIBI_PACKAGE_VERSIONS ?? KIBI_PACKAGE_VERSIONS}`);
1166
+ console.error(`[prolog debug] runtime=${runtime ?? "unknown"} packages=${kibiPackageVersions()}`);
1146
1167
  }
1147
1168
  settle();
1148
1169
  this.terminationReason = `query timeout: ${goalLabel}`;
@@ -1341,7 +1362,7 @@ writeln('${INTERACTIVE_QUERY_FRAME_END}').
1341
1362
  ].join(", ");
1342
1363
  const runtimeName = process.versions.bun !== undefined ? "bun" : "node";
1343
1364
  const runtimeVersion = process.versions.bun ?? process.versions.node ?? "unknown";
1344
- const packageVersions = process.env.KIBI_PACKAGE_VERSIONS ?? KIBI_PACKAGE_VERSIONS;
1365
+ const packageVersions = kibiPackageVersions();
1345
1366
  let child;
1346
1367
  try {
1347
1368
  const launch = this.launchTarget();
@@ -1720,7 +1741,7 @@ writeln('${INTERACTIVE_QUERY_FRAME_END}').
1720
1741
 
1721
1742
  // ../cli/src/prolog/store-lock.ts
1722
1743
  import { existsSync as existsSync4, rmSync } from "node:fs";
1723
- import { readFileSync as readFileSync2 } from "node:fs";
1744
+ import { readFileSync as readFileSync3 } from "node:fs";
1724
1745
  import { dirname, join } from "node:path";
1725
1746
  var cachedBootId;
1726
1747
  function currentBootId() {
@@ -1731,7 +1752,7 @@ function currentBootId() {
1731
1752
  return cachedBootId;
1732
1753
  }
1733
1754
  try {
1734
- const raw = readFileSync2("/proc/sys/kernel/random/boot_id", "utf8");
1755
+ const raw = readFileSync3("/proc/sys/kernel/random/boot_id", "utf8");
1735
1756
  cachedBootId = raw.trim();
1736
1757
  } catch {
1737
1758
  cachedBootId = null;
@@ -1824,31 +1845,31 @@ import {
1824
1845
  execFileSync as rawExecFileSync,
1825
1846
  execSync as rawExecSync
1826
1847
  } from "node:child_process";
1827
- import * as path5 from "node:path";
1848
+ import * as path6 from "node:path";
1828
1849
 
1829
1850
  // ../cli/src/utils/branch-store-locator.ts
1830
1851
  import { createHash } from "node:crypto";
1831
1852
  import {
1832
1853
  existsSync as existsSync5,
1833
1854
  mkdirSync,
1834
- readFileSync as readFileSync3,
1855
+ readFileSync as readFileSync4,
1835
1856
  readdirSync,
1836
1857
  statSync as statSync3,
1837
1858
  writeFileSync
1838
1859
  } from "node:fs";
1839
- import path4 from "node:path";
1860
+ import path5 from "node:path";
1840
1861
  var BRANCH_STORE_MANIFEST_VERSION = 1;
1841
1862
  function branchStoreKey(branch) {
1842
1863
  return createHash("sha256").update(branch, "utf8").digest("hex");
1843
1864
  }
1844
1865
  function branchStoresRoot(workspaceRoot) {
1845
- return path4.join(path4.resolve(workspaceRoot), ".kb", "branches");
1866
+ return path5.join(path5.resolve(workspaceRoot), ".kb", "branches");
1846
1867
  }
1847
1868
  function branchStorePath(workspaceRoot, branch) {
1848
- return path4.join(branchStoresRoot(workspaceRoot), branchStoreKey(branch));
1869
+ return path5.join(branchStoresRoot(workspaceRoot), branchStoreKey(branch));
1849
1870
  }
1850
1871
  function branchStoreManifestPath(storePath) {
1851
- return path4.join(storePath, "branch.json");
1872
+ return path5.join(storePath, "branch.json");
1852
1873
  }
1853
1874
  function expectedBranchStoreManifest(branch) {
1854
1875
  return {
@@ -1862,7 +1883,7 @@ function readBranchStoreManifest(storePath) {
1862
1883
  if (!existsSync5(manifestPath))
1863
1884
  return null;
1864
1885
  try {
1865
- const parsed = JSON.parse(readFileSync3(manifestPath, "utf8"));
1886
+ const parsed = JSON.parse(readFileSync4(manifestPath, "utf8"));
1866
1887
  if (parsed.version !== BRANCH_STORE_MANIFEST_VERSION || typeof parsed.branch !== "string" || typeof parsed.key !== "string") {
1867
1888
  return null;
1868
1889
  }
@@ -1878,7 +1899,7 @@ function readBranchStoreManifest(storePath) {
1878
1899
  function branchStoreManifestMatches(storePath, branch) {
1879
1900
  const manifest = readBranchStoreManifest(storePath);
1880
1901
  const expected = expectedBranchStoreManifest(branch);
1881
- return manifest !== null && manifest.version === expected.version && manifest.branch === expected.branch && manifest.key === expected.key && path4.basename(storePath) === expected.key;
1902
+ return manifest !== null && manifest.version === expected.version && manifest.branch === expected.branch && manifest.key === expected.key && path5.basename(storePath) === expected.key;
1882
1903
  }
1883
1904
  function ensureBranchStoreManifest(workspaceRoot, branch) {
1884
1905
  const storePath = branchStorePath(workspaceRoot, branch);
@@ -1923,7 +1944,7 @@ function isValidBranchName(name) {
1923
1944
  const codePoint = character.codePointAt(0) ?? 0;
1924
1945
  return codePoint <= 32 || codePoint === 127;
1925
1946
  });
1926
- if (name.includes("..") || path5.isAbsolute(name) || name.startsWith("/")) {
1947
+ if (name.includes("..") || path6.isAbsolute(name) || name.startsWith("/")) {
1927
1948
  return false;
1928
1949
  }
1929
1950
  if (name.includes("//") || name.endsWith("/") || name.endsWith(".") || name.includes("\\") || name.startsWith("-") || name.includes("@{") || name.includes("..") || hasControlCharacter || /[~^:?*\[\]]/.test(name)) {
@@ -1946,13 +1967,13 @@ function isValidBranchName(name) {
1946
1967
 
1947
1968
  // ../cli/src/utils/canonical-path.ts
1948
1969
  import { lstatSync as lstatSync2, realpathSync as realpathSync2 } from "node:fs";
1949
- import path6 from "node:path";
1970
+ import path7 from "node:path";
1950
1971
  function canonicalFilesystemPath(candidate) {
1951
- let existing = path6.resolve(candidate);
1972
+ let existing = path7.resolve(candidate);
1952
1973
  const missing = [];
1953
1974
  for (;; ) {
1954
1975
  try {
1955
- return path6.resolve(realpathSync2.native(existing), ...missing);
1976
+ return path7.resolve(realpathSync2.native(existing), ...missing);
1956
1977
  } catch (error) {
1957
1978
  if (error.code !== "ENOENT")
1958
1979
  throw error;
@@ -1965,10 +1986,10 @@ function canonicalFilesystemPath(candidate) {
1965
1986
  }
1966
1987
  if (entry !== undefined)
1967
1988
  throw error;
1968
- const parent = path6.dirname(existing);
1989
+ const parent = path7.dirname(existing);
1969
1990
  if (parent === existing)
1970
1991
  throw error;
1971
- missing.unshift(path6.basename(existing));
1992
+ missing.unshift(path7.basename(existing));
1972
1993
  existing = parent;
1973
1994
  }
1974
1995
  }
@@ -1983,7 +2004,10 @@ var READ_LIMITED_METHODS = new Set([
1983
2004
  ]);
1984
2005
  var ENGINE_PROTOCOL_VERSION = 1;
1985
2006
  var ENGINE_IDLE_TIMEOUT_MS = 10 * 60 * 1000;
1986
- var ENGINE_PACKAGE_VERSIONS = process.env.KIBI_PACKAGE_VERSIONS ?? "unknown";
2007
+ function enginePackageVersions() {
2008
+ return kibiPackageVersions();
2009
+ }
2010
+ var ENGINE_PACKAGE_VERSIONS = kibiPackageVersions();
1987
2011
  function engineSwiplIdentity() {
1988
2012
  return swiplIdentity(resolveSwipl());
1989
2013
  }
@@ -1997,16 +2021,16 @@ function requestEngineSignalShutdown(shutdown) {
1997
2021
  };
1998
2022
  }
1999
2023
  function readJournalGeneration(branchPath) {
2000
- const currentPath = path7.join(branchPath, "CURRENT");
2024
+ const currentPath = path8.join(branchPath, "CURRENT");
2001
2025
  if (!existsSync6(currentPath))
2002
2026
  return "";
2003
- return readFileSync4(currentPath, "utf8").trim();
2027
+ return readFileSync5(currentPath, "utf8").trim();
2004
2028
  }
2005
2029
  function readEngineAttachmentIdentity(branchPath) {
2006
2030
  if (!existsSync6(branchPath))
2007
2031
  return null;
2008
2032
  const stats = statSync4(branchPath);
2009
- let resolved = path7.resolve(branchPath);
2033
+ let resolved = path8.resolve(branchPath);
2010
2034
  try {
2011
2035
  resolved = realpathSync3(branchPath);
2012
2036
  } catch {}
@@ -2140,15 +2164,15 @@ function parseFrames(buffer, onFrame) {
2140
2164
  return buffer.subarray(cursor);
2141
2165
  }
2142
2166
  function runtimeDirectory() {
2143
- const configured = process.env.KIBI_RUNTIME_DIR ?? process.env.XDG_RUNTIME_DIR ?? path7.join(os.tmpdir(), "kibi-runtime");
2167
+ const configured = process.env.KIBI_RUNTIME_DIR ?? process.env.XDG_RUNTIME_DIR ?? path8.join(os.tmpdir(), "kibi-runtime");
2144
2168
  if (process.platform === "win32") {
2145
2169
  for (const candidate of [
2146
2170
  configured,
2147
- path7.join(os.tmpdir(), "kibi-runtime")
2171
+ path8.join(os.tmpdir(), "kibi-runtime")
2148
2172
  ]) {
2149
2173
  try {
2150
2174
  mkdirSync2(candidate, { recursive: true, mode: 448 });
2151
- const probe = path7.join(candidate, `.kibi-write-${process.pid}`);
2175
+ const probe = path8.join(candidate, `.kibi-write-${process.pid}`);
2152
2176
  writeFileSync2(probe, "", { mode: 384 });
2153
2177
  unlinkSync(probe);
2154
2178
  return candidate;
@@ -2163,12 +2187,12 @@ function runtimeDirectory() {
2163
2187
  try {
2164
2188
  configuredIdentity = canonicalFilesystemPath(configured);
2165
2189
  } catch {
2166
- configuredIdentity = path7.resolve(configured);
2190
+ configuredIdentity = path8.resolve(configured);
2167
2191
  }
2168
2192
  const configuredKey = createHash2("sha256").update(configuredIdentity).digest("hex").slice(0, 32);
2169
2193
  const candidates = [
2170
2194
  configured,
2171
- path7.join("/tmp", `kb-${euid}-${configuredKey}`)
2195
+ path8.join("/tmp", `kb-${euid}-${configuredKey}`)
2172
2196
  ];
2173
2197
  const maximumBytes = process.platform === "linux" ? 107 : 103;
2174
2198
  const socketName = `kibi-${"0".repeat(32)}.sock`;
@@ -2186,9 +2210,9 @@ function runtimeDirectory() {
2186
2210
  if (!directory.isDirectory() || directory.uid !== euid || (directory.mode & 63) !== 0)
2187
2211
  continue;
2188
2212
  const canonical = canonicalFilesystemPath(candidate);
2189
- if (Buffer.byteLength(path7.join(canonical, socketName), "utf8") > maximumBytes)
2213
+ if (Buffer.byteLength(path8.join(canonical, socketName), "utf8") > maximumBytes)
2190
2214
  continue;
2191
- const probe = path7.join(canonical, `.kibi-write-${randomUUID()}`);
2215
+ const probe = path8.join(canonical, `.kibi-write-${randomUUID()}`);
2192
2216
  writeFileSync2(probe, "", { mode: 384, flag: "wx" });
2193
2217
  unlinkSync(probe);
2194
2218
  return canonical;
@@ -2209,7 +2233,7 @@ function fsyncPath(filePath) {
2209
2233
  }
2210
2234
  }
2211
2235
  function fsyncJournaledBranchStore(branchPath) {
2212
- const rdfRoot = path7.join(branchPath, "rdf");
2236
+ const rdfRoot = path8.join(branchPath, "rdf");
2213
2237
  const directories = [];
2214
2238
  const pending = existsSync6(rdfRoot) ? [rdfRoot] : [];
2215
2239
  while (pending.length > 0) {
@@ -2218,7 +2242,7 @@ function fsyncJournaledBranchStore(branchPath) {
2218
2242
  break;
2219
2243
  directories.push(directory);
2220
2244
  for (const entry of readdirSync2(directory, { withFileTypes: true })) {
2221
- const entryPath = path7.join(directory, entry.name);
2245
+ const entryPath = path8.join(directory, entry.name);
2222
2246
  if (entry.isDirectory())
2223
2247
  pending.push(entryPath);
2224
2248
  else if (entry.isFile() && entry.name !== "lock")
@@ -2226,7 +2250,7 @@ function fsyncJournaledBranchStore(branchPath) {
2226
2250
  }
2227
2251
  }
2228
2252
  for (const metadata of ["CURRENT", "storage.json", "kb.rdf"]) {
2229
- fsyncPath(path7.join(branchPath, metadata));
2253
+ fsyncPath(path8.join(branchPath, metadata));
2230
2254
  }
2231
2255
  if (process.platform !== "win32") {
2232
2256
  for (const directory of directories.reverse())
@@ -2240,22 +2264,22 @@ function engineSocketPath(workspaceRoot, branch) {
2240
2264
  if (process.platform === "win32") {
2241
2265
  return `\\\\.\\pipe\\kibi-${key}`;
2242
2266
  }
2243
- return path7.join(runtimeDirectory(), `kibi-${key}.sock`);
2267
+ return path8.join(runtimeDirectory(), `kibi-${key}.sock`);
2244
2268
  }
2245
2269
  function enginePidPath(workspaceRoot, branch) {
2246
2270
  const socket = engineSocketPath(workspaceRoot, branch);
2247
2271
  if (process.platform === "win32") {
2248
- return path7.join(runtimeDirectory(), `kibi-${createHash2("sha256").update(`${path7.resolve(workspaceRoot)}\x00${branch}`).digest("hex")}.pid`);
2272
+ return path8.join(runtimeDirectory(), `kibi-${createHash2("sha256").update(`${path8.resolve(workspaceRoot)}\x00${branch}`).digest("hex")}.pid`);
2249
2273
  }
2250
2274
  return `${socket}.pid`;
2251
2275
  }
2252
2276
  function recoverStaleJournalLock(branchPath) {
2253
- const lockPath = path7.join(branchPath, "rdf", "lock");
2277
+ const lockPath = path8.join(branchPath, "rdf", "lock");
2254
2278
  if (!existsSync6(lockPath))
2255
2279
  return;
2256
2280
  let contents = "";
2257
2281
  try {
2258
- contents = readFileSync4(lockPath, "utf8");
2282
+ contents = readFileSync5(lockPath, "utf8");
2259
2283
  } catch {
2260
2284
  return;
2261
2285
  }
@@ -2303,12 +2327,12 @@ function connectSocket(socketPath, timeoutMs) {
2303
2327
  }
2304
2328
  async function ensureJournaledBranchStoreAsync(branchPath) {
2305
2329
  mkdirSync2(branchPath, { recursive: true });
2306
- const markerPath = path7.join(branchPath, "storage.json");
2307
- const marker = existsSync6(markerPath) ? readFileSync4(markerPath, "utf8") : "";
2330
+ const markerPath = path8.join(branchPath, "storage.json");
2331
+ const marker = existsSync6(markerPath) ? readFileSync5(markerPath, "utf8") : "";
2308
2332
  if (marker.includes("kibi.rdf-journal.v1")) {
2309
- const rdfDirectory = path7.join(branchPath, "rdf");
2310
- const currentPath = path7.join(branchPath, "CURRENT");
2311
- const sentinelPath = path7.join(branchPath, "kb.rdf");
2333
+ const rdfDirectory = path8.join(branchPath, "rdf");
2334
+ const currentPath = path8.join(branchPath, "CURRENT");
2335
+ const sentinelPath = path8.join(branchPath, "kb.rdf");
2312
2336
  if (!existsSync6(rdfDirectory) || !existsSync6(currentPath)) {
2313
2337
  recoverInterruptedGeneration(branchPath);
2314
2338
  if (existsSync6(rdfDirectory) && existsSync6(currentPath)) {
@@ -2320,9 +2344,9 @@ async function ensureJournaledBranchStoreAsync(branchPath) {
2320
2344
  }
2321
2345
  return;
2322
2346
  }
2323
- const legacyRdf = path7.join(branchPath, "kb.rdf");
2324
- const legacyAudit = path7.join(branchPath, "audit.log");
2325
- const legacyContents = existsSync6(legacyRdf) ? readFileSync4(legacyRdf, "utf8") : "";
2347
+ const legacyRdf = path8.join(branchPath, "kb.rdf");
2348
+ const legacyAudit = path8.join(branchPath, "audit.log");
2349
+ const legacyContents = existsSync6(legacyRdf) ? readFileSync5(legacyRdf, "utf8") : "";
2326
2350
  if (existsSync6(legacyAudit) || existsSync6(legacyRdf) && !legacyContents.includes("kibi.rdf-journal.v1")) {
2327
2351
  rmSync2(rdfDirectory, { recursive: true, force: true });
2328
2352
  rmSync2(currentPath, { force: true });
@@ -2340,29 +2364,29 @@ async function ensureJournaledBranchStoreAsync(branchPath) {
2340
2364
  return;
2341
2365
  }
2342
2366
  }
2343
- const legacyRdf = path7.join(branchPath, "kb.rdf");
2344
- const legacyAudit = path7.join(branchPath, "audit.log");
2367
+ const legacyRdf = path8.join(branchPath, "kb.rdf");
2368
+ const legacyAudit = path8.join(branchPath, "audit.log");
2345
2369
  if (!existsSync6(legacyRdf) && !existsSync6(legacyAudit)) {
2346
- mkdirSync2(path7.join(branchPath, "rdf"), { recursive: true });
2370
+ mkdirSync2(path8.join(branchPath, "rdf"), { recursive: true });
2347
2371
  writeFileSync2(markerPath, `{"format":"kibi.rdf-journal.v1","schemaVersion":1}
2348
2372
  `, { mode: 384 });
2349
- writeFileSync2(path7.join(branchPath, "CURRENT"), `generation-1:0
2373
+ writeFileSync2(path8.join(branchPath, "CURRENT"), `generation-1:0
2350
2374
  `, {
2351
2375
  mode: 384
2352
2376
  });
2353
- writeFileSync2(path7.join(branchPath, "kb.rdf"), `KIBI_STORAGE_FORMAT=kibi.rdf-journal.v1
2377
+ writeFileSync2(path8.join(branchPath, "kb.rdf"), `KIBI_STORAGE_FORMAT=kibi.rdf-journal.v1
2354
2378
  `, { mode: 384 });
2355
2379
  return;
2356
2380
  }
2357
2381
  if (existsSync6(legacyRdf)) {
2358
- const legacyContents = readFileSync4(legacyRdf, "utf8");
2382
+ const legacyContents = readFileSync5(legacyRdf, "utf8");
2359
2383
  if (!/<rdf:RDF(?:\s|>)/.test(legacyContents)) {
2360
2384
  throw new Error(`Legacy Kibi store is corrupt at ${legacyRdf}: expected RDF/XML root`);
2361
2385
  }
2362
2386
  }
2363
- const parent = path7.dirname(branchPath);
2364
- const migrationKey = createHash2("sha256").update(path7.resolve(branchPath)).digest("hex").slice(0, 16);
2365
- const staging = path7.join(parent, `.${migrationKey}.migration.${process.pid}.${Date.now()}`);
2387
+ const parent = path8.dirname(branchPath);
2388
+ const migrationKey = createHash2("sha256").update(path8.resolve(branchPath)).digest("hex").slice(0, 16);
2389
+ const staging = path8.join(parent, `.${migrationKey}.migration.${process.pid}.${Date.now()}`);
2366
2390
  mkdirSync2(staging, { recursive: true, mode: 448 });
2367
2391
  const testOneShot = false;
2368
2392
  const migrator = new PrologProcess({
@@ -2390,35 +2414,35 @@ async function ensureJournaledBranchStoreAsync(branchPath) {
2390
2414
  await migrator.terminate();
2391
2415
  }
2392
2416
  for (const file of ["rdf", "storage.json", "CURRENT"]) {
2393
- const source = path7.join(staging, file);
2417
+ const source = path8.join(staging, file);
2394
2418
  if (!existsSync6(source))
2395
2419
  continue;
2396
- const target = path7.join(branchPath, file);
2420
+ const target = path8.join(branchPath, file);
2397
2421
  if (existsSync6(target))
2398
2422
  rmSync2(target, { recursive: true, force: true });
2399
2423
  renameSync(source, target);
2400
2424
  }
2401
2425
  archiveLegacyFiles(branchPath);
2402
- writeFileSync2(path7.join(branchPath, "kb.rdf"), `KIBI_STORAGE_FORMAT=kibi.rdf-journal.v1
2426
+ writeFileSync2(path8.join(branchPath, "kb.rdf"), `KIBI_STORAGE_FORMAT=kibi.rdf-journal.v1
2403
2427
  `, { mode: 384 });
2404
2428
  fsyncJournaledBranchStore(branchPath);
2405
2429
  rmSync2(staging, { recursive: true, force: true });
2406
2430
  }
2407
2431
  function archiveLegacyFiles(branchPath) {
2408
- const legacyDir = path7.join(branchPath, "legacy");
2432
+ const legacyDir = path8.join(branchPath, "legacy");
2409
2433
  mkdirSync2(legacyDir, { recursive: true, mode: 448 });
2410
2434
  for (const file of ["kb.rdf", "audit.log"]) {
2411
- const source = path7.join(branchPath, file);
2435
+ const source = path8.join(branchPath, file);
2412
2436
  if (!existsSync6(source))
2413
2437
  continue;
2414
2438
  if (file === "kb.rdf") {
2415
- const contents = readFileSync4(source, "utf8");
2439
+ const contents = readFileSync5(source, "utf8");
2416
2440
  if (contents.includes("kibi.rdf-journal.v1"))
2417
2441
  continue;
2418
2442
  }
2419
- const destination = path7.join(legacyDir, file);
2443
+ const destination = path8.join(legacyDir, file);
2420
2444
  if (existsSync6(destination)) {
2421
- renameSync(source, path7.join(legacyDir, `${file}.recovery.${Date.now()}`));
2445
+ renameSync(source, path8.join(legacyDir, `${file}.recovery.${Date.now()}`));
2422
2446
  } else {
2423
2447
  renameSync(source, destination);
2424
2448
  }
@@ -2434,12 +2458,12 @@ function recoverInterruptedGeneration(branchPath) {
2434
2458
  const newest = (prefix) => {
2435
2459
  const candidates = entries.filter((entry) => entry.startsWith(prefix)).sort().reverse();
2436
2460
  const candidate = candidates[0];
2437
- return candidate === undefined ? null : path7.join(branchPath, candidate);
2461
+ return candidate === undefined ? null : path8.join(branchPath, candidate);
2438
2462
  };
2439
2463
  const oldRdf = newest("rdf.old.");
2440
2464
  const oldCurrent = newest("CURRENT.old.");
2441
- const rdfPath = path7.join(branchPath, "rdf");
2442
- const currentPath = path7.join(branchPath, "CURRENT");
2465
+ const rdfPath = path8.join(branchPath, "rdf");
2466
+ const currentPath = path8.join(branchPath, "CURRENT");
2443
2467
  if ((!existsSync6(rdfPath) || !existsSync6(currentPath)) && oldRdf && oldCurrent) {
2444
2468
  try {
2445
2469
  if (existsSync6(rdfPath))
@@ -2481,9 +2505,9 @@ class EngineSession {
2481
2505
  constructor(prolog, branchPath) {
2482
2506
  this.prolog = prolog;
2483
2507
  this.branchPath = branchPath;
2484
- const coreModuleDir = path7.dirname(resolveKbPlPath());
2508
+ const coreModuleDir = path8.dirname(resolveKbPlPath());
2485
2509
  for (const [fileName, label] of ENGINE_PRELOADED_MODULES) {
2486
- const modulePath = path7.join(coreModuleDir, fileName);
2510
+ const modulePath = path8.join(coreModuleDir, fileName);
2487
2511
  this.modules.push({
2488
2512
  goal: `use_module('${quoteProlog(modulePath.replaceAll("\\", "/"))}')`,
2489
2513
  label
@@ -2549,7 +2573,8 @@ async function runEngineDaemon(requestedOptions) {
2549
2573
  await session.boot();
2550
2574
  let attachedIdentity = readEngineAttachmentIdentity(branchPath);
2551
2575
  const serverPrologIdentity = engineSwiplIdentity();
2552
- mkdirSync2(path7.dirname(options.socketPath), { recursive: true, mode: 448 });
2576
+ const serverPackageVersions = enginePackageVersions();
2577
+ mkdirSync2(path8.dirname(options.socketPath), { recursive: true, mode: 448 });
2553
2578
  if (existsSync6(options.socketPath)) {
2554
2579
  const isLivePeerSignal = (error) => {
2555
2580
  if (error && typeof error === "object") {
@@ -2683,15 +2708,16 @@ async function runEngineDaemon(requestedOptions) {
2683
2708
  if (request.protocolVersion !== ENGINE_PROTOCOL_VERSION) {
2684
2709
  throw new Error(`Kibi engine protocol mismatch: client=${request.protocolVersion ?? "missing"}, server=${ENGINE_PROTOCOL_VERSION}`);
2685
2710
  }
2686
- const expectedPackages = process.env.KIBI_PACKAGE_VERSIONS;
2687
- if (expectedPackages !== undefined && request.packageVersions !== expectedPackages) {
2688
- throw new Error(`Kibi engine package-version mismatch: client=${request.packageVersions ?? "missing"}, server=${expectedPackages}`);
2689
- }
2690
2711
  if (canonicalFilesystemPath(request.workspaceRoot ?? "") !== options.workspaceRoot || request.branch !== options.branch) {
2691
2712
  throw new Error("Kibi engine workspace identity mismatch");
2692
2713
  }
2693
- if (request.method !== "handshake" && request.method !== "stop" && request.prologIdentity !== serverPrologIdentity) {
2694
- throw new Error(`Kibi engine SWI-Prolog mismatch: client=${request.prologIdentity ?? "missing"}, server=${serverPrologIdentity}`);
2714
+ if (request.method !== "handshake" && request.method !== "stop") {
2715
+ if (request.packageVersions !== serverPackageVersions) {
2716
+ throw new Error(`Kibi engine package-version mismatch: client=${request.packageVersions ?? "missing"}, server=${serverPackageVersions}`);
2717
+ }
2718
+ if (request.prologIdentity !== serverPrologIdentity) {
2719
+ throw new Error(`Kibi engine SWI-Prolog mismatch: client=${request.prologIdentity ?? "missing"}, server=${serverPrologIdentity}`);
2720
+ }
2695
2721
  }
2696
2722
  if (!isEngineLifecycleRequest(request) && await session.ensureLive()) {
2697
2723
  queryCache.clear();
@@ -2911,7 +2937,10 @@ async function runEngineDaemon(requestedOptions) {
2911
2937
  throw new Error("export.targetDirectory is required");
2912
2938
  return prolog.query(`kb_storage_export('${quoteProlog(request.targetDirectory)}')`);
2913
2939
  case "handshake":
2914
- return { prologIdentity: serverPrologIdentity };
2940
+ return {
2941
+ prologIdentity: serverPrologIdentity,
2942
+ packageVersions: serverPackageVersions
2943
+ };
2915
2944
  case "stop":
2916
2945
  setImmediate(() => void shutdown());
2917
2946
  return { stopped: true };
@@ -2983,7 +3012,7 @@ async function runEngineDaemon(requestedOptions) {
2983
3012
  id: request.id,
2984
3013
  ok: false,
2985
3014
  error: "Kibi engine is shutting down; request was not executed",
2986
- serverPackageVersions: ENGINE_PACKAGE_VERSIONS
3015
+ serverPackageVersions
2987
3016
  });
2988
3017
  return;
2989
3018
  }
@@ -2996,7 +3025,7 @@ async function runEngineDaemon(requestedOptions) {
2996
3025
  id: request.id,
2997
3026
  ok: false,
2998
3027
  error: "Kibi engine request cancelled",
2999
- serverPackageVersions: ENGINE_PACKAGE_VERSIONS
3028
+ serverPackageVersions
3000
3029
  });
3001
3030
  return;
3002
3031
  }
@@ -3006,14 +3035,14 @@ async function runEngineDaemon(requestedOptions) {
3006
3035
  id: request.id,
3007
3036
  ok: true,
3008
3037
  result,
3009
- serverPackageVersions: ENGINE_PACKAGE_VERSIONS
3038
+ serverPackageVersions
3010
3039
  });
3011
3040
  } catch (error) {
3012
3041
  writeSocketFrame(socket, {
3013
3042
  id: request.id,
3014
3043
  ok: false,
3015
3044
  error: error instanceof Error ? error.message : String(error),
3016
- serverPackageVersions: ENGINE_PACKAGE_VERSIONS
3045
+ serverPackageVersions
3017
3046
  });
3018
3047
  } finally {
3019
3048
  cancelledRequests.delete(request.id);
@@ -3057,7 +3086,7 @@ function isEngineDaemonEntrypoint(argv = process.argv, moduleUrl = import.meta.u
3057
3086
  if (typeof entry !== "string" || entry.length === 0)
3058
3087
  return false;
3059
3088
  try {
3060
- return moduleUrl === pathToFileURL(path8.resolve(entry)).href;
3089
+ return moduleUrl === pathToFileURL(path9.resolve(entry)).href;
3061
3090
  } catch {
3062
3091
  return false;
3063
3092
  }