theokit 0.4.0 → 0.5.1
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/{build-D4J7XECU.js → build-2WZ6XXVY.js} +2 -2
- package/dist/{chunk-IEZCAT2I.js → chunk-HNBWZKIQ.js} +6 -5
- package/dist/chunk-HNBWZKIQ.js.map +1 -0
- package/dist/cli/index.js +3 -3
- package/dist/{dev-MJVSRZGF.js → dev-U4UDZFDB.js} +2 -2
- package/dist/{start-CGSZPBAG.js → start-QDRSRNXK.js} +2 -2
- package/package.json +5 -2
- package/dist/chunk-IEZCAT2I.js.map +0 -1
- /package/dist/{build-D4J7XECU.js.map → build-2WZ6XXVY.js.map} +0 -0
- /package/dist/{dev-MJVSRZGF.js.map → dev-U4UDZFDB.js.map} +0 -0
- /package/dist/{start-CGSZPBAG.js.map → start-QDRSRNXK.js.map} +0 -0
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-XMS5VRIK.js";
|
|
6
6
|
import {
|
|
7
7
|
preflightNodeAndBindings
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-HNBWZKIQ.js";
|
|
9
9
|
import {
|
|
10
10
|
importUserModule,
|
|
11
11
|
loadConfig,
|
|
@@ -604,4 +604,4 @@ function relativize3(absPath, root) {
|
|
|
604
604
|
export {
|
|
605
605
|
buildCommand
|
|
606
606
|
};
|
|
607
|
-
//# sourceMappingURL=build-
|
|
607
|
+
//# sourceMappingURL=build-2WZ6XXVY.js.map
|
|
@@ -8,10 +8,11 @@ import { join } from "path";
|
|
|
8
8
|
var NODE_MIN_MAJOR = 22;
|
|
9
9
|
var NODE_MIN_FULL = "22.12.0";
|
|
10
10
|
var BINDINGS_TO_CHECK = [
|
|
11
|
-
// better-sqlite3 is
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
|
|
11
|
+
// better-sqlite3 is optional — used by cost ledger, cron persistence, memory index
|
|
12
|
+
// when installed. Framework boots fine without it. The dev adds it to their
|
|
13
|
+
// project's package.json when they need persistence (Rails pattern: db is in
|
|
14
|
+
// Gemfile, not in rails gem).
|
|
15
|
+
{ pkg: "better-sqlite3", required: false },
|
|
15
16
|
{ pkg: "@lancedb/lancedb", required: false }
|
|
16
17
|
];
|
|
17
18
|
function checkNodeFloor() {
|
|
@@ -100,4 +101,4 @@ Your project pins Node ${pinned} in .nvmrc.` : "";
|
|
|
100
101
|
export {
|
|
101
102
|
preflightNodeAndBindings
|
|
102
103
|
};
|
|
103
|
-
//# sourceMappingURL=chunk-
|
|
104
|
+
//# sourceMappingURL=chunk-HNBWZKIQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/preflight-node-version.ts"],"sourcesContent":["/**\n * Node version + native-binding ABI preflight for `theokit dev` / `theokit build` / `theokit start`.\n *\n * Why this exists:\n * In multi-Node-version setups (developer workflow: Node 22 for one\n * project, Node 20 for another, nvm switching frequently), the\n * `nohup env ...` invocation pattern strips the nvm PATH prefix and\n * the dev server launches under whichever `node` binary is FIRST in\n * PATH at spawn time — NOT the version the calling shell reported.\n *\n * When `theokit dev` boots under the wrong Node, every native binding\n * in `node_modules` (`better-sqlite3`, optionally `@lancedb/lancedb`,\n * etc.) fails with NODE_MODULE_VERSION mismatch on first use. The\n * error message references a low-level binary path; the dev wastes\n * time investigating a process-management issue.\n *\n * This preflight runs UPFRONT (before any module that touches native\n * bindings loads) and emits an actionable error referencing nvm + the\n * pinned `.nvmrc` floor.\n *\n * What it does:\n * 1. Reads `process.versions.node` + `process.versions.modules` (ABI).\n * 2. If Node major < 22, refuse to boot with a nvm install/use hint.\n * 3. If at least one native binding's compiled ABI != current ABI,\n * refuse to boot with a `pnpm rebuild <pkg>` hint.\n *\n * What it does NOT do:\n * * Auto-rebuild — that's the SDK's preflight (vitest setup, sentinel\n * cached). Auto-rebuild in a dev CLI is risky (slow, can run during\n * `pnpm dev` watch loops).\n * * Probe every native dep — only checks the ones the framework KNOWS\n * are required (currently `better-sqlite3` because of the cost\n * ledger + cron persistence + memory index DB).\n *\n * @internal\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { join } from 'node:path'\n\nconst NODE_MIN_MAJOR = 22\nconst NODE_MIN_FULL = '22.12.0'\n\ninterface BindingProbe {\n pkg: string\n /** path under <cwd>/node_modules — used only for the diagnostic message */\n hintPath?: string\n required: boolean\n}\n\nconst BINDINGS_TO_CHECK: readonly BindingProbe[] = [\n // better-sqlite3 is optional — used by cost ledger, cron persistence, memory index\n // when installed. Framework boots fine without it. The dev adds it to their\n // project's package.json when they need persistence (Rails pattern: db is in\n // Gemfile, not in rails gem).\n { pkg: 'better-sqlite3', required: false },\n { pkg: '@lancedb/lancedb', required: false },\n]\n\nfunction checkNodeFloor(): { ok: true } | { ok: false; reason: string } {\n const major = Number.parseInt(process.versions.node.split('.')[0] ?? '0', 10)\n if (major >= NODE_MIN_MAJOR) return { ok: true }\n return {\n ok: false,\n reason:\n `theokit requires Node >= ${NODE_MIN_FULL} (you are running v${process.versions.node}).\\n\\n` +\n 'Quick fix:\\n' +\n ' nvm use 22 # switch to a Node 22.x already installed\\n' +\n \" nvm install 22.12 # install + switch if you don't have it\\n\\n\" +\n 'Why this matters:\\n' +\n ' theokit ships AsyncLocalStorage + native fetch + structured WHATWG\\n' +\n ' Streams optimizations that depend on Node 22 internals. Older Node\\n' +\n ' versions silently miscompile SSR streaming and break native\\n' +\n ' bindings (NODE_MODULE_VERSION mismatch).\\n\\n' +\n 'Production tip: pin your CI runner to `actions/setup-node` v4 with\\n' +\n \" `node-version-file: .nvmrc` — that's what `create-theokit` writes.\",\n }\n}\n\nfunction checkBindingAbi(cwd: string): { ok: true } | { ok: false; reason: string } {\n const offenders: string[] = []\n // Build createRequire from the cwd so we resolve the consumer's deps,\n // NOT theokit's own node_modules.\n const cwdRequire = createRequire(join(cwd, 'package.json'))\n for (const probe of BINDINGS_TO_CHECK) {\n try {\n cwdRequire.resolve(probe.pkg)\n } catch {\n // not installed — required vs optional gates the behaviour\n if (probe.required) {\n offenders.push(`${probe.pkg} (required dep is NOT installed — run \\`pnpm install\\`)`)\n }\n continue\n }\n // Try a dry require — better-sqlite3 dlopens at load-time, so the ABI\n // mismatch surfaces here as a sync throw.\n try {\n cwdRequire(probe.pkg)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n if (/NODE_MODULE_VERSION|was compiled against|did not self-register/.test(msg)) {\n offenders.push(`${probe.pkg} (compiled against different Node ABI)`)\n } else if (probe.required) {\n // surface non-ABI errors verbatim for required deps\n offenders.push(`${probe.pkg} (require failed: ${msg.split('\\n')[0]})`)\n }\n }\n }\n if (offenders.length === 0) return { ok: true }\n return {\n ok: false,\n reason:\n `Native binding ABI mismatch detected (Node v${process.versions.node}, ABI ${process.versions.modules}).\\n\\n` +\n 'Offending packages:\\n' +\n offenders.map((o) => ` - ${o}`).join('\\n') +\n '\\n\\nQuick fix:\\n' +\n ' pnpm rebuild # rebuild ALL native bindings for current Node\\n' +\n ' pnpm rebuild better-sqlite3 # rebuild just one\\n\\n' +\n 'Why this happened:\\n' +\n ' Your `theokit dev` (or build/start) launched under a different\\n' +\n ' Node version than the one used to install/build node_modules.\\n' +\n ' Common cause: `nohup env ...` strips the nvm PATH prefix, so the\\n' +\n ' dev server picked the system `node` instead of `nvm use 22`.\\n\\n' +\n 'Permanent fix:\\n' +\n ' Prefix your dev/start command with the absolute Node 22 path:\\n' +\n ' PATH=\"$(nvm which 22 | xargs dirname):$PATH\" theokit dev\\n' +\n ' Or use direnv with `.envrc` containing `use node 22.12.0`.',\n }\n}\n\n/**\n * Read `.nvmrc` from cwd if present — used only to enrich error messages\n * with the project's pinned floor. Falls back to the framework default.\n *\n * @internal\n */\nfunction readNvmrcFloor(cwd: string): string | undefined {\n const path = join(cwd, '.nvmrc')\n\n if (!existsSync(path)) return undefined\n try {\n return readFileSync(path, 'utf8').trim()\n } catch {\n return undefined\n }\n}\n\n/**\n * Coerce common truthy env-var values to boolean. Every explicit truthy\n * string activates (\"1\", \"true\", \"yes\"); empty/undefined/\"0\"/\"false\" → off.\n *\n * @internal\n */\nfunction envFlagIsTruthy(value: string | undefined): boolean {\n if (value === undefined || value === '') return false\n const v = value.toLowerCase()\n return v !== '0' && v !== 'false' && v !== 'no'\n}\n\n/**\n * Run the Node + ABI preflight. Throws a descriptive Error on mismatch\n * BEFORE any module that imports better-sqlite3 loads. The error message\n * is the only user-facing artefact — caller can rely on `error.message`\n * being a full actionable diagnostic.\n *\n * Escape hatches (env-var; honor production-grade observability):\n * - `THEOKIT_SKIP_NATIVE_PREFLIGHT=1` — skip the ABI/native-binding check\n * entirely (still enforces Node-floor version). Test fixtures + cleanroom\n * consumer envs that don't actually use better-sqlite3 (no audit-log, no\n * LanceDB embedder, etc.) can opt out. Documented as a Phase 6 readiness\n * fix in docs/plans/t5a2-incoming-message-to-request-shape-refactor-plan.md\n * § Test infrastructure prerequisites (Option B).\n *\n * @throws Error with multi-line actionable message when Node version or\n * native binding ABI is wrong.\n * @internal\n */\nexport function preflightNodeAndBindings(cwd: string): void {\n const nodeCheck = checkNodeFloor()\n if (!nodeCheck.ok) {\n const pinned = readNvmrcFloor(cwd)\n const suffix = pinned !== undefined ? `\\n\\nYour project pins Node ${pinned} in .nvmrc.` : ''\n throw new Error(`[theokit preflight] ${nodeCheck.reason}${suffix}`)\n }\n // T5a.2 prerequisite: env-var escape hatch for native-binding ABI check.\n // Node-floor check above stays enforced unconditionally.\n if (envFlagIsTruthy(process.env.THEOKIT_SKIP_NATIVE_PREFLIGHT)) return\n const abiCheck = checkBindingAbi(cwd)\n if (!abiCheck.ok) {\n throw new Error(`[theokit preflight] ${abiCheck.reason}`)\n }\n}\n"],"mappings":";;;;AAqCA,SAAS,YAAY,oBAAoB;AACzC,SAAS,qBAAqB;AAC9B,SAAS,YAAY;AAErB,IAAM,iBAAiB;AACvB,IAAM,gBAAgB;AAStB,IAAM,oBAA6C;AAAA;AAAA;AAAA;AAAA;AAAA,EAKjD,EAAE,KAAK,kBAAkB,UAAU,MAAM;AAAA,EACzC,EAAE,KAAK,oBAAoB,UAAU,MAAM;AAC7C;AAEA,SAAS,iBAA+D;AACtE,QAAM,QAAQ,OAAO,SAAS,QAAQ,SAAS,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE;AAC5E,MAAI,SAAS,eAAgB,QAAO,EAAE,IAAI,KAAK;AAC/C,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,QACE,4BAA4B,aAAa,sBAAsB,QAAQ,SAAS,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWxF;AACF;AAEA,SAAS,gBAAgB,KAA2D;AAClF,QAAM,YAAsB,CAAC;AAG7B,QAAM,aAAa,cAAc,KAAK,KAAK,cAAc,CAAC;AAC1D,aAAW,SAAS,mBAAmB;AACrC,QAAI;AACF,iBAAW,QAAQ,MAAM,GAAG;AAAA,IAC9B,QAAQ;AAEN,UAAI,MAAM,UAAU;AAClB,kBAAU,KAAK,GAAG,MAAM,GAAG,8DAAyD;AAAA,MACtF;AACA;AAAA,IACF;AAGA,QAAI;AACF,iBAAW,MAAM,GAAG;AAAA,IACtB,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,UAAI,iEAAiE,KAAK,GAAG,GAAG;AAC9E,kBAAU,KAAK,GAAG,MAAM,GAAG,wCAAwC;AAAA,MACrE,WAAW,MAAM,UAAU;AAEzB,kBAAU,KAAK,GAAG,MAAM,GAAG,qBAAqB,IAAI,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AACA,MAAI,UAAU,WAAW,EAAG,QAAO,EAAE,IAAI,KAAK;AAC9C,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,QACE,+CAA+C,QAAQ,SAAS,IAAI,SAAS,QAAQ,SAAS,OAAO;AAAA;AAAA;AAAA,IAErG,UAAU,IAAI,CAAC,MAAM,OAAO,CAAC,EAAE,EAAE,KAAK,IAAI,IAC1C;AAAA,EAYJ;AACF;AAQA,SAAS,eAAe,KAAiC;AACvD,QAAM,OAAO,KAAK,KAAK,QAAQ;AAE/B,MAAI,CAAC,WAAW,IAAI,EAAG,QAAO;AAC9B,MAAI;AACF,WAAO,aAAa,MAAM,MAAM,EAAE,KAAK;AAAA,EACzC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQA,SAAS,gBAAgB,OAAoC;AAC3D,MAAI,UAAU,UAAa,UAAU,GAAI,QAAO;AAChD,QAAM,IAAI,MAAM,YAAY;AAC5B,SAAO,MAAM,OAAO,MAAM,WAAW,MAAM;AAC7C;AAoBO,SAAS,yBAAyB,KAAmB;AAC1D,QAAM,YAAY,eAAe;AACjC,MAAI,CAAC,UAAU,IAAI;AACjB,UAAM,SAAS,eAAe,GAAG;AACjC,UAAM,SAAS,WAAW,SAAY;AAAA;AAAA,yBAA8B,MAAM,gBAAgB;AAC1F,UAAM,IAAI,MAAM,uBAAuB,UAAU,MAAM,GAAG,MAAM,EAAE;AAAA,EACpE;AAGA,MAAI,gBAAgB,QAAQ,IAAI,6BAA6B,EAAG;AAChE,QAAM,WAAW,gBAAgB,GAAG;AACpC,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,uBAAuB,SAAS,MAAM,EAAE;AAAA,EAC1D;AACF;","names":[]}
|
package/dist/cli/index.js
CHANGED
|
@@ -6,12 +6,12 @@ import "../chunk-KT3MWNZG.js";
|
|
|
6
6
|
import cac from "cac";
|
|
7
7
|
var cli = cac("theokit");
|
|
8
8
|
cli.command("dev", "Start development server").option("--port <port>", "Port number").action(async (options) => {
|
|
9
|
-
const { devCommand } = await import("../dev-
|
|
9
|
+
const { devCommand } = await import("../dev-U4UDZFDB.js");
|
|
10
10
|
await devCommand({ port: options.port ? Number(options.port) : void 0 });
|
|
11
11
|
});
|
|
12
12
|
cli.command("build", "Build for production").option("--target <target>", "Deploy target (node, vercel, cloudflare)").action(async (options) => {
|
|
13
13
|
try {
|
|
14
|
-
const { buildCommand } = await import("../build-
|
|
14
|
+
const { buildCommand } = await import("../build-2WZ6XXVY.js");
|
|
15
15
|
await buildCommand({ target: options.target });
|
|
16
16
|
} catch (err) {
|
|
17
17
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -23,7 +23,7 @@ cli.command("build", "Build for production").option("--target <target>", "Deploy
|
|
|
23
23
|
});
|
|
24
24
|
cli.command("start", "Start production server").option("--port <port>", "Port number").action(async (options) => {
|
|
25
25
|
try {
|
|
26
|
-
const { startCommand } = await import("../start-
|
|
26
|
+
const { startCommand } = await import("../start-QDRSRNXK.js");
|
|
27
27
|
await startCommand({ port: options.port ? Number(options.port) : void 0 });
|
|
28
28
|
} catch (err) {
|
|
29
29
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-XMS5VRIK.js";
|
|
6
6
|
import {
|
|
7
7
|
preflightNodeAndBindings
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-HNBWZKIQ.js";
|
|
9
9
|
import {
|
|
10
10
|
theoPluginAsync
|
|
11
11
|
} from "./chunk-M2EY7KDR.js";
|
|
@@ -89,4 +89,4 @@ export {
|
|
|
89
89
|
devCommand,
|
|
90
90
|
startDevServer
|
|
91
91
|
};
|
|
92
|
-
//# sourceMappingURL=dev-
|
|
92
|
+
//# sourceMappingURL=dev-U4UDZFDB.js.map
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import "tsx/esm";
|
|
3
3
|
import {
|
|
4
4
|
preflightNodeAndBindings
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-HNBWZKIQ.js";
|
|
6
6
|
import {
|
|
7
7
|
buildSecurityHeaders,
|
|
8
8
|
createPluginRunnerFromConfig,
|
|
@@ -612,4 +612,4 @@ export {
|
|
|
612
612
|
resolveSsrEntry,
|
|
613
613
|
startCommand
|
|
614
614
|
};
|
|
615
|
-
//# sourceMappingURL=start-
|
|
615
|
+
//# sourceMappingURL=start-QDRSRNXK.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "theokit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -117,7 +117,10 @@
|
|
|
117
117
|
"superjson": "^2.2.6",
|
|
118
118
|
"tsx": "^4.19.0",
|
|
119
119
|
"typescript": "^5.0.0",
|
|
120
|
-
"vite": "^6.0.0"
|
|
120
|
+
"vite": "^6.0.0",
|
|
121
|
+
"@theokit/http": "^0.5.0",
|
|
122
|
+
"@theokit/agents": "^0.4.0",
|
|
123
|
+
"reflect-metadata": "^0.2.0"
|
|
121
124
|
},
|
|
122
125
|
"peerDependencies": {
|
|
123
126
|
"@theokit/ui": "^0.14.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/preflight-node-version.ts"],"sourcesContent":["/**\n * Node version + native-binding ABI preflight for `theokit dev` / `theokit build` / `theokit start`.\n *\n * Why this exists:\n * In multi-Node-version setups (developer workflow: Node 22 for one\n * project, Node 20 for another, nvm switching frequently), the\n * `nohup env ...` invocation pattern strips the nvm PATH prefix and\n * the dev server launches under whichever `node` binary is FIRST in\n * PATH at spawn time — NOT the version the calling shell reported.\n *\n * When `theokit dev` boots under the wrong Node, every native binding\n * in `node_modules` (`better-sqlite3`, optionally `@lancedb/lancedb`,\n * etc.) fails with NODE_MODULE_VERSION mismatch on first use. The\n * error message references a low-level binary path; the dev wastes\n * time investigating a process-management issue.\n *\n * This preflight runs UPFRONT (before any module that touches native\n * bindings loads) and emits an actionable error referencing nvm + the\n * pinned `.nvmrc` floor.\n *\n * What it does:\n * 1. Reads `process.versions.node` + `process.versions.modules` (ABI).\n * 2. If Node major < 22, refuse to boot with a nvm install/use hint.\n * 3. If at least one native binding's compiled ABI != current ABI,\n * refuse to boot with a `pnpm rebuild <pkg>` hint.\n *\n * What it does NOT do:\n * * Auto-rebuild — that's the SDK's preflight (vitest setup, sentinel\n * cached). Auto-rebuild in a dev CLI is risky (slow, can run during\n * `pnpm dev` watch loops).\n * * Probe every native dep — only checks the ones the framework KNOWS\n * are required (currently `better-sqlite3` because of the cost\n * ledger + cron persistence + memory index DB).\n *\n * @internal\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { join } from 'node:path'\n\nconst NODE_MIN_MAJOR = 22\nconst NODE_MIN_FULL = '22.12.0'\n\ninterface BindingProbe {\n pkg: string\n /** path under <cwd>/node_modules — used only for the diagnostic message */\n hintPath?: string\n required: boolean\n}\n\nconst BINDINGS_TO_CHECK: readonly BindingProbe[] = [\n // better-sqlite3 is the only HARD-required native dep at framework boot\n // (cost ledger + cron persistence + memory index). Other native deps\n // (@lancedb/lancedb) are opt-in peers — preflight skips them when absent.\n { pkg: 'better-sqlite3', required: true },\n { pkg: '@lancedb/lancedb', required: false },\n]\n\nfunction checkNodeFloor(): { ok: true } | { ok: false; reason: string } {\n const major = Number.parseInt(process.versions.node.split('.')[0] ?? '0', 10)\n if (major >= NODE_MIN_MAJOR) return { ok: true }\n return {\n ok: false,\n reason:\n `theokit requires Node >= ${NODE_MIN_FULL} (you are running v${process.versions.node}).\\n\\n` +\n 'Quick fix:\\n' +\n ' nvm use 22 # switch to a Node 22.x already installed\\n' +\n \" nvm install 22.12 # install + switch if you don't have it\\n\\n\" +\n 'Why this matters:\\n' +\n ' theokit ships AsyncLocalStorage + native fetch + structured WHATWG\\n' +\n ' Streams optimizations that depend on Node 22 internals. Older Node\\n' +\n ' versions silently miscompile SSR streaming and break native\\n' +\n ' bindings (NODE_MODULE_VERSION mismatch).\\n\\n' +\n 'Production tip: pin your CI runner to `actions/setup-node` v4 with\\n' +\n \" `node-version-file: .nvmrc` — that's what `create-theokit` writes.\",\n }\n}\n\nfunction checkBindingAbi(cwd: string): { ok: true } | { ok: false; reason: string } {\n const offenders: string[] = []\n // Build createRequire from the cwd so we resolve the consumer's deps,\n // NOT theokit's own node_modules.\n const cwdRequire = createRequire(join(cwd, 'package.json'))\n for (const probe of BINDINGS_TO_CHECK) {\n try {\n cwdRequire.resolve(probe.pkg)\n } catch {\n // not installed — required vs optional gates the behaviour\n if (probe.required) {\n offenders.push(`${probe.pkg} (required dep is NOT installed — run \\`pnpm install\\`)`)\n }\n continue\n }\n // Try a dry require — better-sqlite3 dlopens at load-time, so the ABI\n // mismatch surfaces here as a sync throw.\n try {\n cwdRequire(probe.pkg)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n if (/NODE_MODULE_VERSION|was compiled against|did not self-register/.test(msg)) {\n offenders.push(`${probe.pkg} (compiled against different Node ABI)`)\n } else if (probe.required) {\n // surface non-ABI errors verbatim for required deps\n offenders.push(`${probe.pkg} (require failed: ${msg.split('\\n')[0]})`)\n }\n }\n }\n if (offenders.length === 0) return { ok: true }\n return {\n ok: false,\n reason:\n `Native binding ABI mismatch detected (Node v${process.versions.node}, ABI ${process.versions.modules}).\\n\\n` +\n 'Offending packages:\\n' +\n offenders.map((o) => ` - ${o}`).join('\\n') +\n '\\n\\nQuick fix:\\n' +\n ' pnpm rebuild # rebuild ALL native bindings for current Node\\n' +\n ' pnpm rebuild better-sqlite3 # rebuild just one\\n\\n' +\n 'Why this happened:\\n' +\n ' Your `theokit dev` (or build/start) launched under a different\\n' +\n ' Node version than the one used to install/build node_modules.\\n' +\n ' Common cause: `nohup env ...` strips the nvm PATH prefix, so the\\n' +\n ' dev server picked the system `node` instead of `nvm use 22`.\\n\\n' +\n 'Permanent fix:\\n' +\n ' Prefix your dev/start command with the absolute Node 22 path:\\n' +\n ' PATH=\"$(nvm which 22 | xargs dirname):$PATH\" theokit dev\\n' +\n ' Or use direnv with `.envrc` containing `use node 22.12.0`.',\n }\n}\n\n/**\n * Read `.nvmrc` from cwd if present — used only to enrich error messages\n * with the project's pinned floor. Falls back to the framework default.\n *\n * @internal\n */\nfunction readNvmrcFloor(cwd: string): string | undefined {\n const path = join(cwd, '.nvmrc')\n // eslint-disable-next-line security/detect-non-literal-fs-filename -- CLI reads consumer's own .nvmrc; consumer owns cwd\n if (!existsSync(path)) return undefined\n try {\n // eslint-disable-next-line security/detect-non-literal-fs-filename -- same\n return readFileSync(path, 'utf8').trim()\n } catch {\n return undefined\n }\n}\n\n/**\n * Coerce common truthy env-var values to boolean. Every explicit truthy\n * string activates (\"1\", \"true\", \"yes\"); empty/undefined/\"0\"/\"false\" → off.\n *\n * @internal\n */\nfunction envFlagIsTruthy(value: string | undefined): boolean {\n if (value === undefined || value === '') return false\n const v = value.toLowerCase()\n return v !== '0' && v !== 'false' && v !== 'no'\n}\n\n/**\n * Run the Node + ABI preflight. Throws a descriptive Error on mismatch\n * BEFORE any module that imports better-sqlite3 loads. The error message\n * is the only user-facing artefact — caller can rely on `error.message`\n * being a full actionable diagnostic.\n *\n * Escape hatches (env-var; honor production-grade observability):\n * - `THEOKIT_SKIP_NATIVE_PREFLIGHT=1` — skip the ABI/native-binding check\n * entirely (still enforces Node-floor version). Test fixtures + cleanroom\n * consumer envs that don't actually use better-sqlite3 (no audit-log, no\n * LanceDB embedder, etc.) can opt out. Documented as a Phase 6 readiness\n * fix in docs/plans/t5a2-incoming-message-to-request-shape-refactor-plan.md\n * § Test infrastructure prerequisites (Option B).\n *\n * @throws Error with multi-line actionable message when Node version or\n * native binding ABI is wrong.\n * @internal\n */\nexport function preflightNodeAndBindings(cwd: string): void {\n const nodeCheck = checkNodeFloor()\n if (!nodeCheck.ok) {\n const pinned = readNvmrcFloor(cwd)\n const suffix = pinned !== undefined ? `\\n\\nYour project pins Node ${pinned} in .nvmrc.` : ''\n throw new Error(`[theokit preflight] ${nodeCheck.reason}${suffix}`)\n }\n // T5a.2 prerequisite: env-var escape hatch for native-binding ABI check.\n // Node-floor check above stays enforced unconditionally.\n if (envFlagIsTruthy(process.env.THEOKIT_SKIP_NATIVE_PREFLIGHT)) return\n const abiCheck = checkBindingAbi(cwd)\n if (!abiCheck.ok) {\n throw new Error(`[theokit preflight] ${abiCheck.reason}`)\n }\n}\n"],"mappings":";;;;AAqCA,SAAS,YAAY,oBAAoB;AACzC,SAAS,qBAAqB;AAC9B,SAAS,YAAY;AAErB,IAAM,iBAAiB;AACvB,IAAM,gBAAgB;AAStB,IAAM,oBAA6C;AAAA;AAAA;AAAA;AAAA,EAIjD,EAAE,KAAK,kBAAkB,UAAU,KAAK;AAAA,EACxC,EAAE,KAAK,oBAAoB,UAAU,MAAM;AAC7C;AAEA,SAAS,iBAA+D;AACtE,QAAM,QAAQ,OAAO,SAAS,QAAQ,SAAS,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK,KAAK,EAAE;AAC5E,MAAI,SAAS,eAAgB,QAAO,EAAE,IAAI,KAAK;AAC/C,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,QACE,4BAA4B,aAAa,sBAAsB,QAAQ,SAAS,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWxF;AACF;AAEA,SAAS,gBAAgB,KAA2D;AAClF,QAAM,YAAsB,CAAC;AAG7B,QAAM,aAAa,cAAc,KAAK,KAAK,cAAc,CAAC;AAC1D,aAAW,SAAS,mBAAmB;AACrC,QAAI;AACF,iBAAW,QAAQ,MAAM,GAAG;AAAA,IAC9B,QAAQ;AAEN,UAAI,MAAM,UAAU;AAClB,kBAAU,KAAK,GAAG,MAAM,GAAG,8DAAyD;AAAA,MACtF;AACA;AAAA,IACF;AAGA,QAAI;AACF,iBAAW,MAAM,GAAG;AAAA,IACtB,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,UAAI,iEAAiE,KAAK,GAAG,GAAG;AAC9E,kBAAU,KAAK,GAAG,MAAM,GAAG,wCAAwC;AAAA,MACrE,WAAW,MAAM,UAAU;AAEzB,kBAAU,KAAK,GAAG,MAAM,GAAG,qBAAqB,IAAI,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AACA,MAAI,UAAU,WAAW,EAAG,QAAO,EAAE,IAAI,KAAK;AAC9C,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,QACE,+CAA+C,QAAQ,SAAS,IAAI,SAAS,QAAQ,SAAS,OAAO;AAAA;AAAA;AAAA,IAErG,UAAU,IAAI,CAAC,MAAM,OAAO,CAAC,EAAE,EAAE,KAAK,IAAI,IAC1C;AAAA,EAYJ;AACF;AAQA,SAAS,eAAe,KAAiC;AACvD,QAAM,OAAO,KAAK,KAAK,QAAQ;AAE/B,MAAI,CAAC,WAAW,IAAI,EAAG,QAAO;AAC9B,MAAI;AAEF,WAAO,aAAa,MAAM,MAAM,EAAE,KAAK;AAAA,EACzC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQA,SAAS,gBAAgB,OAAoC;AAC3D,MAAI,UAAU,UAAa,UAAU,GAAI,QAAO;AAChD,QAAM,IAAI,MAAM,YAAY;AAC5B,SAAO,MAAM,OAAO,MAAM,WAAW,MAAM;AAC7C;AAoBO,SAAS,yBAAyB,KAAmB;AAC1D,QAAM,YAAY,eAAe;AACjC,MAAI,CAAC,UAAU,IAAI;AACjB,UAAM,SAAS,eAAe,GAAG;AACjC,UAAM,SAAS,WAAW,SAAY;AAAA;AAAA,yBAA8B,MAAM,gBAAgB;AAC1F,UAAM,IAAI,MAAM,uBAAuB,UAAU,MAAM,GAAG,MAAM,EAAE;AAAA,EACpE;AAGA,MAAI,gBAAgB,QAAQ,IAAI,6BAA6B,EAAG;AAChE,QAAM,WAAW,gBAAgB,GAAG;AACpC,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,uBAAuB,SAAS,MAAM,EAAE;AAAA,EAC1D;AACF;","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|