mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-07-10 01:39:25 +00:00
chore(kimi-code): upgrade pi-tui to 0.78.1 and adapt native helpers
Bump @earendil-works/pi-tui from ^0.74.0 to ^0.78.1. pi-tui 0.75.5 replaced its koffi-based Windows VT input with a bundled native helper, and 0.76.0 added a darwin native helper for Terminal.app Shift+Enter. - SEA build: teach native-deps to collect pi-tui's per-target .node files, drop the koffi registry, and add a native-file-only collect mode so only package.json + the target .node ship (28 -> 2 files). - Redirect pi-tui's absolute-path native require() into the native-asset cache through the Module._load hook, and extend the native smoke test to actually load the helper. - npm package: ship pi-tui's native/ directory so macOS Terminal.app Shift+Enter and Windows Shift+Tab keep working for npm installs.
This commit is contained in:
parent
3e98e709b3
commit
0ec5bd62c0
14 changed files with 249 additions and 77 deletions
BIN
apps/kimi-code/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node
Executable file
BIN
apps/kimi-code/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node
Executable file
Binary file not shown.
BIN
apps/kimi-code/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node
Executable file
BIN
apps/kimi-code/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node
Executable file
Binary file not shown.
70
apps/kimi-code/native/darwin/src/darwin-modifiers.c
Normal file
70
apps/kimi-code/native/darwin/src/darwin-modifiers.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NAPI_AUTO_LENGTH ((size_t)-1)
|
||||
|
||||
typedef void* napi_env;
|
||||
typedef void* napi_value;
|
||||
typedef void* napi_callback_info;
|
||||
typedef napi_value (*napi_callback)(napi_env, napi_callback_info);
|
||||
typedef int (*napi_create_function_fn)(napi_env, const char*, size_t, napi_callback, void*, napi_value*);
|
||||
typedef int (*napi_set_named_property_fn)(napi_env, napi_value, const char*, napi_value);
|
||||
typedef int (*napi_get_boolean_fn)(napi_env, bool, napi_value*);
|
||||
typedef int (*napi_get_cb_info_fn)(napi_env, napi_callback_info, size_t*, napi_value*, napi_value*, void**);
|
||||
typedef int (*napi_get_value_string_utf8_fn)(napi_env, napi_value, char*, size_t, size_t*);
|
||||
|
||||
static void* node_symbol(const char* name) {
|
||||
return dlsym(RTLD_DEFAULT, name);
|
||||
}
|
||||
|
||||
static CGEventFlags modifier_mask_for_name(const char* name) {
|
||||
if (strcmp(name, "shift") == 0) return kCGEventFlagMaskShift;
|
||||
if (strcmp(name, "command") == 0) return kCGEventFlagMaskCommand;
|
||||
if (strcmp(name, "control") == 0) return kCGEventFlagMaskControl;
|
||||
if (strcmp(name, "option") == 0) return kCGEventFlagMaskAlternate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static napi_value is_modifier_pressed(napi_env env, napi_callback_info info) {
|
||||
napi_get_cb_info_fn napi_get_cb_info = (napi_get_cb_info_fn)node_symbol("napi_get_cb_info");
|
||||
napi_get_value_string_utf8_fn napi_get_value_string_utf8 = (napi_get_value_string_utf8_fn)node_symbol("napi_get_value_string_utf8");
|
||||
napi_get_boolean_fn napi_get_boolean = (napi_get_boolean_fn)node_symbol("napi_get_boolean");
|
||||
|
||||
bool pressed = false;
|
||||
if (napi_get_cb_info && napi_get_value_string_utf8) {
|
||||
size_t argc = 1;
|
||||
napi_value args[1] = {0};
|
||||
if (napi_get_cb_info(env, info, &argc, args, 0, 0) == 0 && argc >= 1 && args[0]) {
|
||||
char name[16] = {0};
|
||||
size_t copied = 0;
|
||||
if (napi_get_value_string_utf8(env, args[0], name, sizeof(name), &copied) == 0) {
|
||||
CGEventFlags mask = modifier_mask_for_name(name);
|
||||
if (mask != 0) {
|
||||
CGEventFlags flags = CGEventSourceFlagsState(kCGEventSourceStateCombinedSessionState);
|
||||
pressed = (flags & mask) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
napi_value result = 0;
|
||||
if (napi_get_boolean) napi_get_boolean(env, pressed, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
__attribute__((visibility("default"))) napi_value napi_register_module_v1(napi_env env, napi_value exports) {
|
||||
napi_create_function_fn napi_create_function = (napi_create_function_fn)node_symbol("napi_create_function");
|
||||
napi_set_named_property_fn napi_set_named_property = (napi_set_named_property_fn)node_symbol("napi_set_named_property");
|
||||
|
||||
napi_value fn = 0;
|
||||
if (napi_create_function &&
|
||||
napi_set_named_property &&
|
||||
napi_create_function(env, "isModifierPressed", NAPI_AUTO_LENGTH, is_modifier_pressed, 0, &fn) == 0) {
|
||||
napi_set_named_property(env, exports, "isModifierPressed", fn);
|
||||
}
|
||||
|
||||
return exports;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
53
apps/kimi-code/native/win32/src/win32-console-mode.c
Normal file
53
apps/kimi-code/native/win32/src/win32-console-mode.c
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#include <windows.h>
|
||||
|
||||
#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
|
||||
#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
|
||||
#endif
|
||||
|
||||
#define NAPI_AUTO_LENGTH ((unsigned long long)-1)
|
||||
|
||||
typedef void* napi_env;
|
||||
typedef void* napi_value;
|
||||
typedef void* napi_callback_info;
|
||||
typedef napi_value (__cdecl *napi_callback)(napi_env, napi_callback_info);
|
||||
typedef int (__cdecl *napi_create_function_fn)(napi_env, const char*, unsigned long long, napi_callback, void*, napi_value*);
|
||||
typedef int (__cdecl *napi_set_named_property_fn)(napi_env, napi_value, const char*, napi_value);
|
||||
typedef int (__cdecl *napi_get_boolean_fn)(napi_env, int, napi_value*);
|
||||
|
||||
static void* node_symbol(const char* name) {
|
||||
HMODULE module = GetModuleHandleA(0);
|
||||
void* proc = module ? (void*)GetProcAddress(module, name) : 0;
|
||||
if (proc) return proc;
|
||||
|
||||
module = GetModuleHandleA("node.dll");
|
||||
return module ? (void*)GetProcAddress(module, name) : 0;
|
||||
}
|
||||
|
||||
static napi_value __cdecl enable_virtual_terminal_input(napi_env env, napi_callback_info info) {
|
||||
(void)info;
|
||||
|
||||
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
DWORD mode = 0;
|
||||
int enabled = handle != INVALID_HANDLE_VALUE &&
|
||||
GetConsoleMode(handle, &mode) &&
|
||||
SetConsoleMode(handle, mode | ENABLE_VIRTUAL_TERMINAL_INPUT);
|
||||
|
||||
napi_get_boolean_fn napi_get_boolean = (napi_get_boolean_fn)node_symbol("napi_get_boolean");
|
||||
napi_value result = 0;
|
||||
if (napi_get_boolean) napi_get_boolean(env, enabled, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
__declspec(dllexport) napi_value __cdecl napi_register_module_v1(napi_env env, napi_value exports) {
|
||||
napi_create_function_fn napi_create_function = (napi_create_function_fn)node_symbol("napi_create_function");
|
||||
napi_set_named_property_fn napi_set_named_property = (napi_set_named_property_fn)node_symbol("napi_set_named_property");
|
||||
|
||||
napi_value fn = 0;
|
||||
if (napi_create_function &&
|
||||
napi_set_named_property &&
|
||||
napi_create_function(env, "enableVirtualTerminalInput", NAPI_AUTO_LENGTH, enable_virtual_terminal_input, 0, &fn) == 0) {
|
||||
napi_set_named_property(env, exports, "enableVirtualTerminalInput", fn);
|
||||
}
|
||||
|
||||
return exports;
|
||||
}
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
"files": [
|
||||
"dist",
|
||||
"dist-web",
|
||||
"native",
|
||||
"scripts/postinstall.mjs",
|
||||
"scripts/postinstall",
|
||||
"README.md"
|
||||
|
|
@ -75,11 +76,10 @@
|
|||
},
|
||||
"optionalDependencies": {
|
||||
"@mariozechner/clipboard": "^0.3.9",
|
||||
"koffi": "^2.16.0",
|
||||
"node-pty": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@earendil-works/pi-tui": "^0.74.0",
|
||||
"@earendil-works/pi-tui": "^0.78.1",
|
||||
"@moonshot-ai/acp-adapter": "workspace:^",
|
||||
"@moonshot-ai/kimi-code-oauth": "workspace:^",
|
||||
"@moonshot-ai/kimi-code-sdk": "workspace:^",
|
||||
|
|
|
|||
|
|
@ -17,9 +17,7 @@ export const NATIVE_TARGETS = Object.freeze(
|
|||
SUPPORTED_TARGETS.map((t) => {
|
||||
const deps = resolveTargetDeps(t);
|
||||
const clipboardTarget = deps.find((d) => d.id === 'clipboard-target')?.resolvedName;
|
||||
const koffiNativeFile = deps.find((d) => d.id === 'koffi')?.nativeFileRelatives?.[0];
|
||||
const koffiTriplet = koffiNativeFile?.match(/koffi\/([^/]+)\/koffi\.node$/)?.[1] ?? null;
|
||||
return [t, { clipboardPackage: clipboardTarget, koffiTriplet }];
|
||||
return [t, { clipboardPackage: clipboardTarget }];
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
|
@ -161,16 +159,19 @@ async function collectPackageFiles({
|
|||
packageName,
|
||||
packageRoot,
|
||||
includeNativeFiles,
|
||||
includeEntryJs = true,
|
||||
nativeFileRelatives = [],
|
||||
}) {
|
||||
const packageJsonPath = join(packageRoot, 'package.json');
|
||||
const packageJson = await readJson(packageJsonPath);
|
||||
const selected = new Set([packageJsonPath]);
|
||||
|
||||
const entry = resolvePackageEntry(packageRoot, packageJson);
|
||||
if (entry !== null) {
|
||||
selected.add(entry);
|
||||
await addRuntimeDependencyFiles(packageRoot, entry, selected);
|
||||
if (includeEntryJs) {
|
||||
const entry = resolvePackageEntry(packageRoot, packageJson);
|
||||
if (entry !== null) {
|
||||
selected.add(entry);
|
||||
await addRuntimeDependencyFiles(packageRoot, entry, selected);
|
||||
}
|
||||
}
|
||||
|
||||
for (const nativeFileRelative of nativeFileRelatives) {
|
||||
|
|
@ -250,6 +251,7 @@ export async function collectNativeAssets({ appRoot, target }) {
|
|||
packageName: dep.resolvedName,
|
||||
packageRoot,
|
||||
includeNativeFiles: dep.collect === 'native-files',
|
||||
includeEntryJs: dep.collect !== 'native-file-only',
|
||||
nativeFileRelatives: dep.nativeFileRelatives,
|
||||
});
|
||||
const result = await packageManifestEntries({
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const optionalRuntimeRequires = new Set([
|
|||
'utf-8-validate',
|
||||
]);
|
||||
const optionalRelativeRuntimeRequires = new Set(['./crypto/build/Release/sshcrypto.node']);
|
||||
const handledNativeRuntimeRequires = new Set(['koffi']);
|
||||
const handledNativeRuntimeRequires = new Set();
|
||||
|
||||
function isAllowedSpecifier(specifier) {
|
||||
if (builtins.has(specifier) || specifier.startsWith('node:')) return true;
|
||||
|
|
|
|||
|
|
@ -27,13 +27,16 @@ const clipboardSubpackageByTarget = Object.freeze({
|
|||
'win32-x64': '@mariozechner/clipboard-win32-x64-msvc',
|
||||
});
|
||||
|
||||
const koffiTripletByTarget = Object.freeze({
|
||||
'darwin-arm64': 'darwin_arm64',
|
||||
'darwin-x64': 'darwin_x64',
|
||||
'linux-arm64': 'linux_arm64',
|
||||
'linux-x64': 'linux_x64',
|
||||
'win32-arm64': 'win32_arm64',
|
||||
'win32-x64': 'win32_x64',
|
||||
// pi-tui ships platform-specific native helpers (no Linux build):
|
||||
// - darwin: Shift-modifier detection for Terminal.app Shift+Enter
|
||||
// - win32: enable ENABLE_VIRTUAL_TERMINAL_INPUT so Shift+Tab is distinguishable
|
||||
const piTuiNativeFileByTarget = Object.freeze({
|
||||
'darwin-arm64': ['native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node'],
|
||||
'darwin-x64': ['native/darwin/prebuilds/darwin-x64/darwin-modifiers.node'],
|
||||
'linux-arm64': [],
|
||||
'linux-x64': [],
|
||||
'win32-arm64': ['native/win32/prebuilds/win32-arm64/win32-console-mode.node'],
|
||||
'win32-x64': ['native/win32/prebuilds/win32-x64/win32-console-mode.node'],
|
||||
});
|
||||
|
||||
export function isSupportedTarget(target) {
|
||||
|
|
@ -45,13 +48,15 @@ export function isSupportedTarget(target) {
|
|||
* @property {string} id — stable internal id used for parent refs
|
||||
* @property {(target: string) => string} name
|
||||
* — npm package name (may depend on target)
|
||||
* @property {'js-only'|'native-files'|'js-and-native-file'|'virtual'} collect
|
||||
* @property {'js-only'|'native-files'|'js-and-native-file'|'native-file-only'|'virtual'} collect
|
||||
* @property {string|null} parent
|
||||
* — id of another registered dep this nests under (for pnpm),
|
||||
* or null for top-level (resolvable from app root)
|
||||
* @property {(target: string) => string[]} [nativeFileRelatives]
|
||||
* — explicit list of .node files relative to package root
|
||||
* (used by 'js-and-native-file'; native-files mode auto-scans *.node)
|
||||
* (used by 'js-and-native-file' and 'native-file-only';
|
||||
* native-files mode auto-scans *.node). 'native-file-only' collects
|
||||
* package.json + these .node files but skips the package entry JS.
|
||||
*/
|
||||
|
||||
/** @type {readonly NativeDepDescriptor[]} */
|
||||
|
|
@ -71,17 +76,13 @@ export const nativeDeps = Object.freeze([
|
|||
{
|
||||
id: 'pi-tui',
|
||||
name: () => '@earendil-works/pi-tui',
|
||||
// pi-tui is bundled into main.cjs at build time — we don't collect it as
|
||||
// a native dep, only register it so koffi can declare it as parent.
|
||||
collect: 'virtual',
|
||||
// pi-tui's JS is bundled into main.cjs, so only the platform-specific
|
||||
// native helper (.node under native/) ships alongside the binary — its
|
||||
// dist/ JS is intentionally NOT collected (it stays in the bundle). This
|
||||
// keeps the SEA native-asset payload small. Linux has no native helper.
|
||||
collect: 'native-file-only',
|
||||
parent: null,
|
||||
},
|
||||
{
|
||||
id: 'koffi',
|
||||
name: () => 'koffi',
|
||||
collect: 'js-and-native-file',
|
||||
parent: 'pi-tui',
|
||||
nativeFileRelatives: (target) => [`build/koffi/${koffiTripletByTarget[target]}/koffi.node`],
|
||||
nativeFileRelatives: (target) => piTuiNativeFileByTarget[target] ?? [],
|
||||
},
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import { existsSync } from 'node:fs';
|
||||
import { createRequire } from 'node:module';
|
||||
import { join } from 'node:path';
|
||||
|
||||
import { loadNativePackage } from './native-require';
|
||||
import { getNativePackageRoot } from './native-assets';
|
||||
|
||||
type ModuleLoad = (request: string, parent: unknown, isMain: boolean) => unknown;
|
||||
|
||||
|
|
@ -10,7 +12,16 @@ interface ModuleWithLoad {
|
|||
|
||||
const nodeRequire = createRequire(import.meta.url);
|
||||
let installed = false;
|
||||
let loadingNativePackage = false;
|
||||
|
||||
// pi-tui loads its platform-specific native helpers via an absolute-path
|
||||
// require() computed from import.meta.url / process.execPath
|
||||
// (see pi-tui dist/terminal.js and dist/native-modifiers.js). In a SEA binary
|
||||
// those .node files live in the native-asset cache, so redirect any absolute
|
||||
// require of a pi-tui native helper to the cached copy.
|
||||
//
|
||||
// Path shape: native/<darwin|win32>/prebuilds/<arch>/<file>.node — note the
|
||||
// two path segments after "prebuilds", so ".+" (not "[^/]+") is required.
|
||||
const PI_TUI_NATIVE_PATTERN = /native[\\/](?:win32|darwin)[\\/]prebuilds[\\/].+\.node$/;
|
||||
|
||||
export function installNativeModuleHook(): void {
|
||||
if (installed) return;
|
||||
|
|
@ -26,13 +37,18 @@ export function installNativeModuleHook(): void {
|
|||
parent: unknown,
|
||||
isMain: boolean,
|
||||
): unknown {
|
||||
if (request === 'koffi' && !loadingNativePackage) {
|
||||
loadingNativePackage = true;
|
||||
try {
|
||||
const pkg = loadNativePackage<unknown>('koffi');
|
||||
if (pkg !== null) return pkg;
|
||||
} finally {
|
||||
loadingNativePackage = false;
|
||||
if (
|
||||
typeof request === 'string' &&
|
||||
PI_TUI_NATIVE_PATTERN.test(request) &&
|
||||
!existsSync(request)
|
||||
) {
|
||||
const pkgRoot = getNativePackageRoot('@earendil-works/pi-tui');
|
||||
if (pkgRoot !== null) {
|
||||
const match = request.match(PI_TUI_NATIVE_PATTERN);
|
||||
if (match !== null) {
|
||||
const redirected = join(pkgRoot, match[0]);
|
||||
return originalLoad.call(this, redirected, parent, isMain);
|
||||
}
|
||||
}
|
||||
}
|
||||
return originalLoad.call(this, request, parent, isMain);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,38 @@
|
|||
import { createRequire } from 'node:module';
|
||||
import { dirname, join } from 'node:path';
|
||||
|
||||
import { getEmbeddedNativeAssetManifest, getNativePackageRoot } from './native-assets';
|
||||
|
||||
const smokePackages = ['@mariozechner/clipboard', 'koffi'];
|
||||
const smokePackages = ['@mariozechner/clipboard', '@earendil-works/pi-tui'];
|
||||
|
||||
// Verify pi-tui's native helper can actually be loaded through the module hook.
|
||||
// pi-tui computes native helper paths from process.execPath and require()s them;
|
||||
// those paths do not exist next to the SEA binary, so this only succeeds when
|
||||
// installNativeModuleHook() redirects the require into the native-asset cache.
|
||||
function smokePiTuiNativeLoad(): void {
|
||||
const platform = process.platform;
|
||||
const arch = process.arch;
|
||||
let rel: string | undefined;
|
||||
if (platform === 'darwin' && (arch === 'x64' || arch === 'arm64')) {
|
||||
rel = join('native', 'darwin', 'prebuilds', `darwin-${arch}`, 'darwin-modifiers.node');
|
||||
} else if (platform === 'win32' && (arch === 'x64' || arch === 'arm64')) {
|
||||
rel = join('native', 'win32', 'prebuilds', `win32-${arch}`, 'win32-console-mode.node');
|
||||
}
|
||||
if (rel === undefined) return; // Linux: no native helper, nothing to load.
|
||||
|
||||
const req = createRequire(import.meta.url);
|
||||
const bogusPath = join(dirname(process.execPath), rel);
|
||||
const helper = req(bogusPath) as {
|
||||
isModifierPressed?: unknown;
|
||||
enableVirtualTerminalInput?: unknown;
|
||||
};
|
||||
const ok =
|
||||
typeof helper.isModifierPressed === 'function' ||
|
||||
typeof helper.enableVirtualTerminalInput === 'function';
|
||||
if (!ok) {
|
||||
throw new Error(`pi-tui native helper loaded but exports are unexpected: ${rel}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function runNativeAssetSmokeIfRequested(): boolean {
|
||||
if (process.env['KIMI_CODE_NATIVE_ASSET_SMOKE'] !== '1') return false;
|
||||
|
|
@ -16,6 +48,7 @@ export function runNativeAssetSmokeIfRequested(): boolean {
|
|||
throw new Error(`Native package is not available: ${packageName}`);
|
||||
}
|
||||
}
|
||||
smokePiTuiNativeLoad();
|
||||
process.stdout.write(`Native asset smoke passed: ${manifest.target}\n`);
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ describe('resolveTargetDeps', () => {
|
|||
const names = deps.map((d) => d.resolvedName);
|
||||
expect(names).toContain('@mariozechner/clipboard');
|
||||
expect(names).toContain('@mariozechner/clipboard-darwin-arm64');
|
||||
expect(names).toContain('koffi');
|
||||
expect(names).toContain('@earendil-works/pi-tui');
|
||||
});
|
||||
|
||||
it('picks the right clipboard subpackage per target', () => {
|
||||
|
|
@ -56,13 +56,23 @@ describe('resolveTargetDeps', () => {
|
|||
).toContain('@mariozechner/clipboard-win32-arm64-msvc');
|
||||
});
|
||||
|
||||
it('encodes koffi native file path with target triplet', () => {
|
||||
const linuxKoffi = resolveTargetDeps('linux-arm64').find((d) => d.resolvedName === 'koffi');
|
||||
expect(linuxKoffi?.nativeFileRelatives).toEqual(['build/koffi/linux_arm64/koffi.node']);
|
||||
const macKoffi = resolveTargetDeps('darwin-x64').find((d) => d.resolvedName === 'koffi');
|
||||
expect(macKoffi?.nativeFileRelatives).toEqual(['build/koffi/darwin_x64/koffi.node']);
|
||||
const winArmKoffi = resolveTargetDeps('win32-arm64').find((d) => d.resolvedName === 'koffi');
|
||||
expect(winArmKoffi?.nativeFileRelatives).toEqual(['build/koffi/win32_arm64/koffi.node']);
|
||||
it('encodes pi-tui native file path per target', () => {
|
||||
const linuxPiTui = resolveTargetDeps('linux-arm64').find(
|
||||
(d) => d.resolvedName === '@earendil-works/pi-tui',
|
||||
);
|
||||
expect(linuxPiTui?.nativeFileRelatives).toEqual([]);
|
||||
const macPiTui = resolveTargetDeps('darwin-x64').find(
|
||||
(d) => d.resolvedName === '@earendil-works/pi-tui',
|
||||
);
|
||||
expect(macPiTui?.nativeFileRelatives).toEqual([
|
||||
'native/darwin/prebuilds/darwin-x64/darwin-modifiers.node',
|
||||
]);
|
||||
const winArmPiTui = resolveTargetDeps('win32-arm64').find(
|
||||
(d) => d.resolvedName === '@earendil-works/pi-tui',
|
||||
);
|
||||
expect(winArmPiTui?.nativeFileRelatives).toEqual([
|
||||
'native/win32/prebuilds/win32-arm64/win32-console-mode.node',
|
||||
]);
|
||||
});
|
||||
|
||||
it('throws on unsupported target', () => {
|
||||
|
|
@ -82,9 +92,9 @@ describe('nativeDeps registry shape', () => {
|
|||
expect(target?.parent).toBe('clipboard-host');
|
||||
});
|
||||
|
||||
it('has koffi (collect=js-and-native-file, parent=pi-tui)', () => {
|
||||
const koffi = nativeDeps.find((d) => d.id === 'koffi');
|
||||
expect(koffi?.collect).toBe('js-and-native-file');
|
||||
expect(koffi?.parent).toBe('pi-tui');
|
||||
it('has pi-tui (collect=native-file-only, no parent)', () => {
|
||||
const piTui = nativeDeps.find((d) => d.id === 'pi-tui');
|
||||
expect(piTui?.collect).toBe('native-file-only');
|
||||
expect(piTui?.parent).toBe(null);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
39
pnpm-lock.yaml
generated
39
pnpm-lock.yaml
generated
|
|
@ -73,8 +73,8 @@ importers:
|
|||
apps/kimi-code:
|
||||
devDependencies:
|
||||
'@earendil-works/pi-tui':
|
||||
specifier: ^0.74.0
|
||||
version: 0.74.0
|
||||
specifier: ^0.78.1
|
||||
version: 0.78.1
|
||||
'@moonshot-ai/acp-adapter':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/acp-adapter
|
||||
|
|
@ -142,9 +142,6 @@ importers:
|
|||
'@mariozechner/clipboard':
|
||||
specifier: ^0.3.9
|
||||
version: 0.3.9
|
||||
koffi:
|
||||
specifier: ^2.16.0
|
||||
version: 2.16.0
|
||||
node-pty:
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0
|
||||
|
|
@ -984,9 +981,9 @@ packages:
|
|||
search-insights:
|
||||
optional: true
|
||||
|
||||
'@earendil-works/pi-tui@0.74.0':
|
||||
resolution: {integrity: sha512-1aIfXZp7D/z+1VlZX8BZcs6pgO8rjmil7kwyhctNDsWvce3Yfl8GVgu4eq+I0Mjhr8Cj+ipBiv9CLIzdoyCOIQ==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
'@earendil-works/pi-tui@0.78.1':
|
||||
resolution: {integrity: sha512-07GVQo/38a0yvIPlWDr3RJn1B8gk3ZuIX9h2oIQ+Biyu3JN0KppWmgWHfaWRydQgse5JtC++KDw5MWaIRnV0mw==}
|
||||
engines: {node: '>=22.19.0'}
|
||||
|
||||
'@emnapi/core@1.10.0':
|
||||
resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==}
|
||||
|
|
@ -2699,9 +2696,6 @@ packages:
|
|||
'@types/mdurl@2.0.0':
|
||||
resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
|
||||
|
||||
'@types/mime-types@2.1.4':
|
||||
resolution: {integrity: sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==}
|
||||
|
||||
'@types/ms@2.1.0':
|
||||
resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
|
||||
|
||||
|
|
@ -3932,6 +3926,10 @@ packages:
|
|||
resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
get-east-asian-width@1.6.0:
|
||||
resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
|
@ -4383,9 +4381,6 @@ packages:
|
|||
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
koffi@2.16.0:
|
||||
resolution: {integrity: sha512-h/2NJueOKWd0YYycEOWDspomizgNfuOKf/V7ZE2fytvuRtHoY9Tb+y4x6GJ6pFqaVndWn9dLK+sCI14eWtu5rA==}
|
||||
|
||||
layout-base@1.0.2:
|
||||
resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==}
|
||||
|
||||
|
|
@ -6867,15 +6862,10 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- '@algolia/client-search'
|
||||
|
||||
'@earendil-works/pi-tui@0.74.0':
|
||||
'@earendil-works/pi-tui@0.78.1':
|
||||
dependencies:
|
||||
'@types/mime-types': 2.1.4
|
||||
chalk: 5.6.2
|
||||
get-east-asian-width: 1.5.0
|
||||
get-east-asian-width: 1.6.0
|
||||
marked: 15.0.12
|
||||
mime-types: 3.0.2
|
||||
optionalDependencies:
|
||||
koffi: 2.16.0
|
||||
|
||||
'@emnapi/core@1.10.0':
|
||||
dependencies:
|
||||
|
|
@ -8189,8 +8179,6 @@ snapshots:
|
|||
|
||||
'@types/mdurl@2.0.0': {}
|
||||
|
||||
'@types/mime-types@2.1.4': {}
|
||||
|
||||
'@types/ms@2.1.0': {}
|
||||
|
||||
'@types/node@12.20.55': {}
|
||||
|
|
@ -9621,6 +9609,8 @@ snapshots:
|
|||
|
||||
get-east-asian-width@1.5.0: {}
|
||||
|
||||
get-east-asian-width@1.6.0: {}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
|
|
@ -10101,9 +10091,6 @@ snapshots:
|
|||
|
||||
kind-of@6.0.3: {}
|
||||
|
||||
koffi@2.16.0:
|
||||
optional: true
|
||||
|
||||
layout-base@1.0.2: {}
|
||||
|
||||
layout-base@2.0.1: {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue