mirror of
https://github.com/Narcooo/inkos.git
synced 2026-08-28 23:02:03 +08:00
chore: require node 22 runtime
This commit is contained in:
+1
-1
@@ -35,7 +35,7 @@
|
||||
"release": "pnpm build && pnpm test"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0",
|
||||
"node": ">=22.0.0",
|
||||
"pnpm": ">=9.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,8 +552,7 @@ describe("CLI integration", () => {
|
||||
it("checks environment health", () => {
|
||||
const { stdout } = runStderr(["doctor"]);
|
||||
expect(stdout).toContain("InkOS Doctor");
|
||||
expect(stdout).toContain("Node.js >= 20");
|
||||
expect(stdout).toContain("SQLite memory index");
|
||||
expect(stdout).toContain("Node.js >= 22");
|
||||
expect(stdout).toContain("inkos.json");
|
||||
});
|
||||
|
||||
|
||||
@@ -4,8 +4,7 @@ import { join } from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import {
|
||||
ensureNodeRuntimePinFiles,
|
||||
evaluateSqliteMemorySupport,
|
||||
formatSqliteMemorySupportWarning,
|
||||
evaluateNodeRuntimeSupport,
|
||||
inspectNodeRuntimePinFiles,
|
||||
parseNodeMajor,
|
||||
} from "../runtime-requirements.js";
|
||||
@@ -26,8 +25,8 @@ describe("runtime requirements", () => {
|
||||
expect(parseNodeMajor("v22.19.0")).toBe(22);
|
||||
});
|
||||
|
||||
it("marks sqlite memory acceleration unavailable below Node 22", () => {
|
||||
const result = evaluateSqliteMemorySupport({
|
||||
it("rejects runtimes below Node 22", () => {
|
||||
const result = evaluateNodeRuntimeSupport({
|
||||
nodeVersion: "v20.17.0",
|
||||
hasNodeSqlite: false,
|
||||
});
|
||||
@@ -37,8 +36,8 @@ describe("runtime requirements", () => {
|
||||
expect(result.detail).toContain("v20.17.0");
|
||||
});
|
||||
|
||||
it("marks sqlite memory acceleration available on supported runtimes", () => {
|
||||
const result = evaluateSqliteMemorySupport({
|
||||
it("accepts supported runtimes", () => {
|
||||
const result = evaluateNodeRuntimeSupport({
|
||||
nodeVersion: "v22.19.0",
|
||||
hasNodeSqlite: true,
|
||||
});
|
||||
@@ -47,26 +46,6 @@ describe("runtime requirements", () => {
|
||||
expect(result.detail).toContain("v22.19.0");
|
||||
});
|
||||
|
||||
it("formats an early warning for unsupported sqlite memory runtimes", () => {
|
||||
const warning = formatSqliteMemorySupportWarning({
|
||||
nodeVersion: "v20.17.0",
|
||||
hasNodeSqlite: false,
|
||||
});
|
||||
|
||||
expect(warning).toContain("v20.17.0");
|
||||
expect(warning).toContain("Node 22+");
|
||||
expect(warning).toContain("memory.db live sync");
|
||||
});
|
||||
|
||||
it("does not format a warning on supported runtimes", () => {
|
||||
const warning = formatSqliteMemorySupportWarning({
|
||||
nodeVersion: "v22.19.0",
|
||||
hasNodeSqlite: true,
|
||||
});
|
||||
|
||||
expect(warning).toBeNull();
|
||||
});
|
||||
|
||||
it("reports missing node runtime pin files", async () => {
|
||||
const status = await inspectNodeRuntimePinFiles(tempRoot);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { findProjectRoot, log, logError, GLOBAL_ENV_PATH } from "../utils.js";
|
||||
import { fetchWithProxy } from "@actalk/inkos-core";
|
||||
import {
|
||||
ensureNodeRuntimePinFiles,
|
||||
evaluateSqliteMemorySupport,
|
||||
evaluateNodeRuntimeSupport,
|
||||
inspectNodeRuntimePinFiles,
|
||||
} from "../runtime-requirements.js";
|
||||
import {
|
||||
@@ -123,15 +123,9 @@ export const doctorCommand = new Command("doctor")
|
||||
|
||||
// 1. Check Node.js version
|
||||
const nodeVersion = process.version;
|
||||
const major = parseInt(nodeVersion.slice(1).split(".")[0]!, 10);
|
||||
checks.push({
|
||||
name: "Node.js >= 20",
|
||||
ok: major >= 20,
|
||||
detail: nodeVersion,
|
||||
});
|
||||
checks.push({
|
||||
name: "SQLite memory index (Node 22+)",
|
||||
...evaluateSqliteMemorySupport({ nodeVersion }),
|
||||
name: "Node.js >= 22",
|
||||
...evaluateNodeRuntimeSupport({ nodeVersion }),
|
||||
});
|
||||
checks.push({
|
||||
name: "Node runtime pin files",
|
||||
|
||||
@@ -4,11 +4,11 @@ import { createRequire } from "node:module";
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
export const SQLITE_MEMORY_MIN_NODE_MAJOR = 22;
|
||||
export const SQLITE_MEMORY_PIN_VERSION = String(SQLITE_MEMORY_MIN_NODE_MAJOR);
|
||||
export const SQLITE_MEMORY_PIN_FILES = [".nvmrc", ".node-version"] as const;
|
||||
export const MIN_NODE_MAJOR = 22;
|
||||
export const NODE_PIN_VERSION = String(MIN_NODE_MAJOR);
|
||||
export const NODE_PIN_FILES = [".nvmrc", ".node-version"] as const;
|
||||
|
||||
export interface SqliteMemorySupportResult {
|
||||
export interface NodeRuntimeSupportResult {
|
||||
readonly ok: boolean;
|
||||
readonly detail: string;
|
||||
}
|
||||
@@ -24,27 +24,13 @@ export interface NodeRuntimePinRepairResult {
|
||||
readonly written: ReadonlyArray<string>;
|
||||
}
|
||||
|
||||
export function formatSqliteMemorySupportWarning(options?: {
|
||||
readonly nodeVersion?: string;
|
||||
readonly hasNodeSqlite?: boolean;
|
||||
}): string | null {
|
||||
const nodeVersion = options?.nodeVersion ?? process.version;
|
||||
const result = evaluateSqliteMemorySupport({
|
||||
nodeVersion,
|
||||
hasNodeSqlite: options?.hasNodeSqlite,
|
||||
});
|
||||
if (result.ok) return null;
|
||||
|
||||
return `Node ${nodeVersion} does not support SQLite memory index; memory.db live sync will fall back to Markdown. Use Node 22+ or run 'inkos doctor'.`;
|
||||
}
|
||||
|
||||
export async function inspectNodeRuntimePinFiles(root: string): Promise<NodeRuntimePinStatus> {
|
||||
const missing: string[] = [];
|
||||
|
||||
for (const file of SQLITE_MEMORY_PIN_FILES) {
|
||||
for (const file of NODE_PIN_FILES) {
|
||||
try {
|
||||
const content = await readFile(join(root, file), "utf-8");
|
||||
if (content.trim() !== SQLITE_MEMORY_PIN_VERSION) {
|
||||
if (content.trim() !== NODE_PIN_VERSION) {
|
||||
missing.push(file);
|
||||
}
|
||||
} catch {
|
||||
@@ -55,7 +41,7 @@ export async function inspectNodeRuntimePinFiles(root: string): Promise<NodeRunt
|
||||
if (missing.length === 0) {
|
||||
return {
|
||||
ok: true,
|
||||
detail: `Pinned to Node ${SQLITE_MEMORY_PIN_VERSION} via ${SQLITE_MEMORY_PIN_FILES.join(", ")}.`,
|
||||
detail: `Pinned to Node ${NODE_PIN_VERSION} via ${NODE_PIN_FILES.join(", ")}.`,
|
||||
missing,
|
||||
};
|
||||
}
|
||||
@@ -70,7 +56,7 @@ export async function inspectNodeRuntimePinFiles(root: string): Promise<NodeRunt
|
||||
export async function ensureNodeRuntimePinFiles(root: string): Promise<NodeRuntimePinRepairResult> {
|
||||
const written: string[] = [];
|
||||
|
||||
for (const file of SQLITE_MEMORY_PIN_FILES) {
|
||||
for (const file of NODE_PIN_FILES) {
|
||||
const path = join(root, file);
|
||||
let content = "";
|
||||
try {
|
||||
@@ -79,11 +65,11 @@ export async function ensureNodeRuntimePinFiles(root: string): Promise<NodeRunti
|
||||
content = "";
|
||||
}
|
||||
|
||||
if (content.trim() === SQLITE_MEMORY_PIN_VERSION) {
|
||||
if (content.trim() === NODE_PIN_VERSION) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await writeFile(path, `${SQLITE_MEMORY_PIN_VERSION}\n`, "utf-8");
|
||||
await writeFile(path, `${NODE_PIN_VERSION}\n`, "utf-8");
|
||||
written.push(file);
|
||||
}
|
||||
|
||||
@@ -106,17 +92,17 @@ function hasNodeSqliteBuiltin(): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
export function evaluateSqliteMemorySupport(options?: {
|
||||
export function evaluateNodeRuntimeSupport(options?: {
|
||||
readonly nodeVersion?: string;
|
||||
readonly hasNodeSqlite?: boolean;
|
||||
}): SqliteMemorySupportResult {
|
||||
}): NodeRuntimeSupportResult {
|
||||
const nodeVersion = options?.nodeVersion ?? process.version;
|
||||
const major = parseNodeMajor(nodeVersion);
|
||||
|
||||
if (major < SQLITE_MEMORY_MIN_NODE_MAJOR) {
|
||||
if (major < MIN_NODE_MAJOR) {
|
||||
return {
|
||||
ok: false,
|
||||
detail: `Unavailable on ${nodeVersion}. Long-book memory.db acceleration requires Node ${SQLITE_MEMORY_MIN_NODE_MAJOR}+.`,
|
||||
detail: `Unsupported runtime ${nodeVersion}. InkOS requires Node ${MIN_NODE_MAJOR}+.`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -124,7 +110,7 @@ export function evaluateSqliteMemorySupport(options?: {
|
||||
if (!hasNodeSqlite) {
|
||||
return {
|
||||
ok: false,
|
||||
detail: `${nodeVersion} detected, but node:sqlite is unavailable on this runtime. memory.db acceleration will stay disabled.`,
|
||||
detail: `${nodeVersion} detected, but the required node:sqlite module is unavailable.`,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { readFile, stat } from "node:fs/promises";
|
||||
import { join, resolve } from "node:path";
|
||||
import { createLLMClient, StateManager, createLogger, createStderrSink, createJsonLineSink, resolveEffectiveLLMConfig, loadLLMEnvLayers, GLOBAL_CONFIG_DIR, GLOBAL_ENV_PATH, type EffectiveLLMConfigResult, type LLMConfigCliOverrides, type ProjectConfig, type PipelineConfig, type LogSink } from "@actalk/inkos-core";
|
||||
import { formatSqliteMemorySupportWarning } from "./runtime-requirements.js";
|
||||
|
||||
export { GLOBAL_CONFIG_DIR, GLOBAL_ENV_PATH };
|
||||
|
||||
let sqliteMemorySupportWarned = false;
|
||||
|
||||
export async function resolveContext(opts: {
|
||||
readonly context?: string;
|
||||
@@ -113,14 +111,6 @@ export function buildPipelineConfig(
|
||||
readonly logFile?: NodeJS.WritableStream;
|
||||
},
|
||||
): PipelineConfig {
|
||||
if (!extra?.quiet && !sqliteMemorySupportWarned) {
|
||||
const warning = formatSqliteMemorySupportWarning();
|
||||
if (warning) {
|
||||
sqliteMemorySupportWarned = true;
|
||||
process.stderr.write(`[WARN] ${warning}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
const sinks: LogSink[] = [];
|
||||
if (!extra?.quiet) {
|
||||
sinks.push(createStderrSink({ minLevel: "info" }));
|
||||
|
||||
Reference in New Issue
Block a user