kibi-swipl 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +25 -2
  2. package/index.d.ts +49 -0
  3. package/index.js +162 -0
  4. package/package.json +39 -4
package/README.md CHANGED
@@ -1,3 +1,26 @@
1
- # Temporary Holding Version
1
+ # kibi-swipl
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Locates the bundled SWI-Prolog runtime that [Kibi](https://github.com/Looted/kibi)
4
+ uses. It is a dependency of `kibi-cli` and `kibi-runtime`; you normally never
5
+ install or import it yourself.
6
+
7
+ `kibi-swipl` lists one platform package per supported target as an optional
8
+ dependency, so the package manager installs only the one that matches the
9
+ machine:
10
+
11
+ | Platform | Package |
12
+ | --- | --- |
13
+ | Linux x64 (glibc) | `kibi-swipl-linux-x64-gnu` |
14
+ | Linux arm64 (glibc) | `kibi-swipl-linux-arm64-gnu` |
15
+ | macOS arm64 | `kibi-swipl-darwin-arm64` |
16
+ | macOS x64 | `kibi-swipl-darwin-x64` |
17
+
18
+ Alpine (musl) and native Windows have no bundle; install SWI-Prolog 9.0+ and put
19
+ `swipl` on `PATH`, or point `KIBI_SWIPL` at it.
20
+
21
+ Kibi resolves SWI-Prolog in this order: `KIBI_SWIPL=<absolute path>`, the bundled
22
+ platform package (after checking its manifest and binary checksum), then `swipl`
23
+ on `PATH` (9.0 or newer). `KIBI_SWIPL=system` skips the bundle.
24
+
25
+ The package versions independently of SWI-Prolog; the upstream version each
26
+ platform package carries is recorded in its `kibi.swiplVersion` field.
package/index.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ export declare const MANIFEST_FILE: "build-manifest.json";
2
+ export declare const MANIFEST_SCHEMA: "kibi.swipl-build.v1";
3
+ export declare const BUNDLED_BINARY_PATH: "bin/swipl";
4
+
5
+ export type PlatformKey =
6
+ | "linux-x64-gnu"
7
+ | "linux-arm64-gnu"
8
+ | "darwin-arm64"
9
+ | "darwin-x64";
10
+
11
+ export type PlatformPackage = {
12
+ readonly package: string;
13
+ readonly os: "linux" | "darwin";
14
+ readonly cpu: "x64" | "arm64";
15
+ readonly libc?: "glibc";
16
+ };
17
+
18
+ export declare const PLATFORM_PACKAGES: Readonly<
19
+ Record<PlatformKey, PlatformPackage>
20
+ >;
21
+
22
+ export declare function platformKey(host: {
23
+ platform: string;
24
+ arch: string;
25
+ /** True only for glibc Linux; musl and unknown libc have no bundle. */
26
+ glibc?: boolean | undefined;
27
+ }): PlatformKey | undefined;
28
+
29
+ export declare function locatePlatformPackage(
30
+ packageName: string,
31
+ requireFrom?: { resolve(request: string): string },
32
+ ): string | undefined;
33
+
34
+ export type BuildManifestValidation =
35
+ | {
36
+ ok: true;
37
+ swiplVersion: string;
38
+ binaryPath: "bin/swipl";
39
+ binarySha256: string;
40
+ home: string;
41
+ }
42
+ | { ok: false; reason: string };
43
+
44
+ export declare function validateBuildManifest(
45
+ manifest: unknown,
46
+ expected: { target: string; swiplVersion?: string | undefined },
47
+ ): BuildManifestValidation;
48
+
49
+ export declare function sha256File(filePath: string): string;
package/index.js ADDED
@@ -0,0 +1,162 @@
1
+ /*
2
+ * Kibi — repo-local, per-branch, queryable long-term memory for software projects
3
+ * Copyright (C) 2026 Piotr Franczyk
4
+ *
5
+ * This program is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU Affero General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ */
10
+
11
+ // Platform table, bundle-manifest validation, and package location for the
12
+ // bundled SWI-Prolog runtime. Kibi's resolver (kibi-cli) owns the lookup order;
13
+ // this module only knows what a valid per-platform package looks like.
14
+
15
+ import { createHash } from "node:crypto";
16
+ import { readFileSync } from "node:fs";
17
+ import { createRequire } from "node:module";
18
+ import path from "node:path";
19
+
20
+ export const MANIFEST_FILE = "build-manifest.json";
21
+ export const MANIFEST_SCHEMA = "kibi.swipl-build.v1";
22
+ export const BUNDLED_BINARY_PATH = "bin/swipl";
23
+
24
+ /** Platform key -> platform package, in a stable documented order. */
25
+ export const PLATFORM_PACKAGES = Object.freeze({
26
+ "linux-x64-gnu": Object.freeze({
27
+ package: "kibi-swipl-linux-x64-gnu",
28
+ os: "linux",
29
+ cpu: "x64",
30
+ libc: "glibc",
31
+ }),
32
+ "linux-arm64-gnu": Object.freeze({
33
+ package: "kibi-swipl-linux-arm64-gnu",
34
+ os: "linux",
35
+ cpu: "arm64",
36
+ libc: "glibc",
37
+ }),
38
+ "darwin-arm64": Object.freeze({
39
+ package: "kibi-swipl-darwin-arm64",
40
+ os: "darwin",
41
+ cpu: "arm64",
42
+ }),
43
+ "darwin-x64": Object.freeze({
44
+ package: "kibi-swipl-darwin-x64",
45
+ os: "darwin",
46
+ cpu: "x64",
47
+ }),
48
+ });
49
+
50
+ /**
51
+ * Map a host to a platform key, or undefined when no bundle is published for
52
+ * it (native Windows, musl Linux, other architectures).
53
+ */
54
+ export function platformKey({ platform, arch, glibc }) {
55
+ if (platform === "linux") {
56
+ if (glibc !== true) return undefined;
57
+ return arch === "x64" || arch === "arm64" ? `linux-${arch}-gnu` : undefined;
58
+ }
59
+ if (platform === "darwin") {
60
+ return arch === "x64" || arch === "arm64" ? `darwin-${arch}` : undefined;
61
+ }
62
+ return undefined;
63
+ }
64
+
65
+ /**
66
+ * Directory of an installed platform package, found from this package's own
67
+ * location (platform packages are optional dependencies of kibi-swipl, so a
68
+ * strict package manager only exposes them here). Undefined when absent.
69
+ */
70
+ export function locatePlatformPackage(
71
+ packageName,
72
+ requireFrom = createRequire(import.meta.url),
73
+ ) {
74
+ try {
75
+ return path.dirname(requireFrom.resolve(`${packageName}/package.json`));
76
+ } catch (error) {
77
+ const code = error && typeof error === "object" ? error.code : undefined;
78
+ if (code === "MODULE_NOT_FOUND" || code === "ERR_PACKAGE_PATH_NOT_EXPORTED")
79
+ return undefined;
80
+ throw error;
81
+ }
82
+ }
83
+
84
+ function safeRelativePath(value) {
85
+ if (typeof value !== "string" || value.length === 0) return false;
86
+ if (value.includes("\\") || value.includes("\0")) return false;
87
+ if (path.posix.isAbsolute(value)) return false;
88
+ const normalized = path.posix.normalize(value);
89
+ return (
90
+ normalized === value &&
91
+ normalized !== "." &&
92
+ !normalized.split("/").includes("..")
93
+ );
94
+ }
95
+
96
+ /**
97
+ * Validate a platform package's build manifest (the swipl-build pipeline's
98
+ * build-manifest.json). Returns { ok: true, ... } or { ok: false, reason }.
99
+ */
100
+ export function validateBuildManifest(manifest, expected) {
101
+ if (
102
+ manifest === null ||
103
+ typeof manifest !== "object" ||
104
+ Array.isArray(manifest)
105
+ )
106
+ return { ok: false, reason: "manifest is not a JSON object" };
107
+ if (manifest.schema !== MANIFEST_SCHEMA)
108
+ return {
109
+ ok: false,
110
+ reason: `manifest schema must be ${MANIFEST_SCHEMA}`,
111
+ };
112
+ if (manifest.target !== expected.target)
113
+ return {
114
+ ok: false,
115
+ reason: `manifest target ${JSON.stringify(manifest.target)} does not match ${expected.target}`,
116
+ };
117
+ if (
118
+ typeof manifest.swiplVersion !== "string" ||
119
+ !/^\d+\.\d+\.\d+$/.test(manifest.swiplVersion)
120
+ )
121
+ return { ok: false, reason: "manifest swiplVersion is missing or invalid" };
122
+ if (
123
+ expected.swiplVersion !== undefined &&
124
+ manifest.swiplVersion !== expected.swiplVersion
125
+ )
126
+ return {
127
+ ok: false,
128
+ reason: `manifest swiplVersion ${manifest.swiplVersion} does not match package kibi.swiplVersion ${expected.swiplVersion}`,
129
+ };
130
+ const binary = manifest.binary;
131
+ if (binary === null || typeof binary !== "object")
132
+ return { ok: false, reason: "manifest binary entry is missing" };
133
+ if (binary.path !== BUNDLED_BINARY_PATH)
134
+ return {
135
+ ok: false,
136
+ reason: `manifest binary.path must be ${BUNDLED_BINARY_PATH}`,
137
+ };
138
+ if (
139
+ typeof binary.sha256 !== "string" ||
140
+ !/^[0-9a-f]{64}$/.test(binary.sha256)
141
+ )
142
+ return {
143
+ ok: false,
144
+ reason: "manifest binary.sha256 must be 64 lowercase hex digits",
145
+ };
146
+ if (!safeRelativePath(manifest.home))
147
+ return {
148
+ ok: false,
149
+ reason: "manifest home must be a normalized relative path",
150
+ };
151
+ return {
152
+ ok: true,
153
+ swiplVersion: manifest.swiplVersion,
154
+ binaryPath: binary.path,
155
+ binarySha256: binary.sha256,
156
+ home: manifest.home,
157
+ };
158
+ }
159
+
160
+ export function sha256File(filePath) {
161
+ return createHash("sha256").update(readFileSync(filePath)).digest("hex");
162
+ }
package/package.json CHANGED
@@ -1,6 +1,41 @@
1
1
  {
2
2
  "name": "kibi-swipl",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "description": "Locates the bundled SWI-Prolog runtime that Kibi uses on this platform",
5
+ "type": "module",
6
+ "main": "./index.js",
7
+ "types": "./index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./index.d.ts",
11
+ "default": "./index.js"
12
+ },
13
+ "./package.json": "./package.json"
14
+ },
15
+ "files": ["index.js", "index.d.ts", "README.md"],
16
+ "scripts": {
17
+ "test": "bun test --timeout 15000 ."
18
+ },
19
+ "engines": {
20
+ "node": ">=22"
21
+ },
22
+ "license": "AGPL-3.0-or-later",
23
+ "author": "Piotr Franczyk",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/Looted/kibi.git",
27
+ "directory": "packages/swipl"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "kibi": {
33
+ "swiplVersion": "10.0.2"
34
+ },
35
+ "optionalDependencies": {
36
+ "kibi-swipl-linux-x64-gnu": "1.0.0",
37
+ "kibi-swipl-linux-arm64-gnu": "1.0.0",
38
+ "kibi-swipl-darwin-arm64": "1.0.0",
39
+ "kibi-swipl-darwin-x64": "1.0.0"
40
+ }
41
+ }