Files
oh-my-pi/packages/natives/native/index.js
T
can1357 5ea1d55e56 feat: removed chunk-mode modules and read/edit entrypoints from pi-natives
- Removed `pi-natives` chunk language classifier modules and all core chunk subsystems (kind, state, render, edit, resolve).
- Removed chunk-mode CLI/read/edit entrypoints, including `read` command and chunk mode registration/prompt tooling.
- Removed chunk selectors from `read` and `grep` tools, switching behavior to raw/L-range handling.
- Fixed poll wait parsing to keep defaulting to `30s` when the provided value is empty.
2026-04-26 08:19:02 +02:00

274 lines
8.2 KiB
JavaScript

/**
* Native addon loader and bindings.
*
* Types are auto-generated by napi-rs in `native/index.d.ts`.
*/
const fs = require("node:fs");
const { createRequire } = require("node:module");
const os = require("node:os");
const path = require("node:path");
function getNativesDir() {
const xdgDataHome = process.env.XDG_DATA_HOME;
if (xdgDataHome && fs.existsSync(path.join(xdgDataHome, "omp"))) {
return path.join(xdgDataHome, "omp", "natives");
}
return path.join(os.homedir(), ".omp", "natives");
}
const packageJson = require("../package.json");
let embeddedAddon = null;
const require_ = createRequire(__filename);
const platformTag = `${process.platform}-${process.arch}`;
const packageVersion = packageJson.version;
const nativeDir = path.join(__dirname, "..", "native");
const execDir = path.dirname(process.execPath);
const versionedDir = path.join(getNativesDir(), packageVersion);
const userDataDir =
process.platform === "win32"
? path.join(process.env.LOCALAPPDATA || path.join(os.homedir(), "AppData", "Local"), "omp")
: path.join(os.homedir(), ".local", "bin");
const isCompiledBinary =
process.env.PI_COMPILED ||
__filename.includes("$bunfs") ||
__filename.includes("~BUN") ||
__filename.includes("%7EBUN");
if (isCompiledBinary) {
try {
({ embeddedAddon } = require("./embedded-addon"));
} catch {
embeddedAddon = null;
}
}
const SUPPORTED_PLATFORMS = ["linux-x64", "linux-arm64", "darwin-x64", "darwin-arm64", "win32-x64"];
function getVariantOverride() {
const value = process.env.PI_NATIVE_VARIANT;
if (!value) return null;
if (value === "modern" || value === "baseline") return value;
return null;
}
function detectAvx2Support() {
if (process.arch !== "x64") {
return false;
}
if (process.platform === "linux") {
try {
const cpuInfo = fs.readFileSync("/proc/cpuinfo", "utf8");
return /\bavx2\b/i.test(cpuInfo);
} catch {
return false;
}
}
if (process.platform === "darwin") {
const leaf7 = runCommand("sysctl", ["-n", "machdep.cpu.leaf7_features"]);
if (leaf7 && /\bAVX2\b/i.test(leaf7)) {
return true;
}
const features = runCommand("sysctl", ["-n", "machdep.cpu.features"]);
return Boolean(features && /\bAVX2\b/i.test(features));
}
if (process.platform === "win32") {
const output = runCommand("powershell.exe", [
"-NoProfile",
"-NonInteractive",
"-Command",
"[System.Runtime.Intrinsics.X86.Avx2]::IsSupported",
]);
return output && output.toLowerCase() === "true";
}
return false;
}
function resolveCpuVariant(override) {
if (process.arch !== "x64") return null;
if (override) return override;
return detectAvx2Support() ? "modern" : "baseline";
}
function getAddonFilenames(tag, variant) {
const defaultFilename = `pi_natives.${tag}.node`;
if (process.arch !== "x64" || !variant) return [defaultFilename];
const baselineFilename = `pi_natives.${tag}-baseline.node`;
const modernFilename = `pi_natives.${tag}-modern.node`;
if (variant === "modern") {
return [modernFilename, baselineFilename, defaultFilename];
}
return [baselineFilename, defaultFilename];
}
const variantOverride = getVariantOverride();
const selectedVariant = resolveCpuVariant(variantOverride);
const addonFilenames = getAddonFilenames(platformTag, selectedVariant);
const addonLabel = selectedVariant ? `${platformTag} (${selectedVariant})` : platformTag;
const baseReleaseCandidates = addonFilenames.flatMap(filename => [
path.join(nativeDir, filename),
path.join(execDir, filename),
]);
const compiledCandidates = addonFilenames.flatMap(filename => [
path.join(versionedDir, filename),
path.join(userDataDir, filename),
]);
const releaseCandidates = isCompiledBinary ? [...compiledCandidates, ...baseReleaseCandidates] : baseReleaseCandidates;
const dedupedCandidates = [...new Set(releaseCandidates)];
function runCommand(command, args) {
// removed logger.time
try {
const { spawnSync } = require("child_process");
const result = spawnSync(command, args, { encoding: "utf-8" });
if (result.error) return null;
if (result.status !== 0) return null;
return (result.stdout || "").trim();
} catch {
return null;
}
}
function selectEmbeddedAddonFile() {
if (!embeddedAddon) return null;
const defaultFile = embeddedAddon.files.find(file => file.variant === "default") || null;
if (process.arch !== "x64") return defaultFile || embeddedAddon.files[0] || null;
if (selectedVariant === "modern") {
return (
embeddedAddon.files.find(file => file.variant === "modern") ||
embeddedAddon.files.find(file => file.variant === "baseline") ||
null
);
}
return embeddedAddon.files.find(file => file.variant === "baseline") || null;
}
function maybeExtractEmbeddedAddon(errors) {
if (!isCompiledBinary || !embeddedAddon) return null;
if (embeddedAddon.platformTag !== platformTag || embeddedAddon.version !== packageVersion) return null;
const selectedEmbeddedFile = selectEmbeddedAddonFile();
if (!selectedEmbeddedFile) return null;
const targetPath = path.join(versionedDir, selectedEmbeddedFile.filename);
try {
fs.mkdirSync(versionedDir, { recursive: true });
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
errors.push(`embedded addon dir: ${message}`);
return null;
}
if (fs.existsSync(targetPath)) {
return targetPath;
}
try {
const buffer = fs.readFileSync(selectedEmbeddedFile.filePath);
fs.writeFileSync(targetPath, buffer);
return targetPath;
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
errors.push(`embedded addon write (${selectedEmbeddedFile.filename}): ${message}`);
return null;
}
}
function loadNative() {
const errors = [];
const embeddedCandidate = maybeExtractEmbeddedAddon(errors);
const runtimeCandidates = embeddedCandidate ? [embeddedCandidate, ...dedupedCandidates] : dedupedCandidates;
for (const candidate of runtimeCandidates) {
try {
const bindings = require_(candidate);
return bindings;
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
errors.push(`${candidate}: ${message}`);
}
}
// Check if this is an unsupported platform
if (!SUPPORTED_PLATFORMS.includes(platformTag)) {
throw new Error(
`Unsupported platform: ${platformTag}\n` +
`Supported platforms: ${SUPPORTED_PLATFORMS.join(", ")}\n` +
"If you need support for this platform, please open an issue.",
);
}
const details = errors.map(error => `- ${error}`).join("\n");
let helpMessage;
if (isCompiledBinary) {
const expectedPaths = addonFilenames.map(filename => ` ${path.join(versionedDir, filename)}`).join("\n");
const downloadHints = addonFilenames
.map(filename => {
const downloadUrl = `https://github.com/can1357/oh-my-pi/releases/latest/download/${filename}`;
const targetPath = path.join(versionedDir, filename);
return ` curl -fsSL "${downloadUrl}" -o "${targetPath}"`;
})
.join("\n");
helpMessage =
`The compiled binary should extract one of:\n${expectedPaths}\n\n` +
`If missing, delete ${versionedDir} and re-run, or download manually:\n${downloadHints}`;
} else {
helpMessage =
"If installed via npm/bun, try reinstalling: bun install @oh-my-pi/pi-natives\n" +
"If developing locally, build with: bun --cwd=packages/natives run build\n" +
"Optional x64 variants: TARGET_VARIANT=baseline|modern bun --cwd=packages/natives run build";
}
throw new Error(`Failed to load pi_natives native addon for ${addonLabel}.\n\nTried:\n${details}\n\n${helpMessage}`);
}
module.exports = loadNative();
// --- generated const enum exports (do not edit) ---
module.exports.AstMatchStrictness = {
Cst: 'cst',
Smart: 'smart',
Ast: 'ast',
Relaxed: 'relaxed',
Signature: 'signature',
Template: 'template',
};
module.exports.Ellipsis = {
Unicode: 0,
Ascii: 1,
Omit: 2,
};
module.exports.FileType = {
File: 1,
Dir: 2,
Symlink: 3,
};
module.exports.GrepOutputMode = {
Content: 'content',
Count: 'count',
FilesWithMatches: 'filesWithMatches',
};
module.exports.ImageFormat = {
PNG: 0,
JPEG: 1,
WEBP: 2,
GIF: 3,
};
module.exports.KeyEventType = {
Press: 1,
Repeat: 2,
Release: 3,
};
module.exports.MacOSAppearance = {
Dark: 'dark',
Light: 'light',
};
module.exports.SamplingFilter = {
Nearest: 1,
Triangle: 2,
CatmullRom: 3,
Gaussian: 4,
Lanczos3: 5,
};
// --- end generated const enum exports ---