fix: fix @nousresearch/ui version, update to npm 12

This commit is contained in:
ethernet
2026-08-01 13:09:47 -04:00
parent d7c24f2646
commit f88ed6c717
22 changed files with 7075 additions and 2609 deletions

View File

@@ -69,6 +69,10 @@ jobs:
cache: npm
cache-dependency-path: website/package-lock.json
- name: grab npm 12
run: |
npm i -g npm@12
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.11'

View File

@@ -19,6 +19,10 @@ jobs:
cache: npm
cache-dependency-path: website/package-lock.json
- name: grab npm 12
run: |
npm i -g npm@12
- name: Install website dependencies
uses: ./.github/actions/retry
with:

View File

@@ -41,6 +41,11 @@ jobs:
with:
node-version: 22
cache: npm
- name: grab npm 12
run: |
npm i -g npm@12
# Full npm ci (not --ignore-scripts): electron's postinstall
# downloads the binary we launch, and node-pty's native build is
# needed for the terminal pane.
@@ -56,7 +61,7 @@ jobs:
# fetching a manifest from raw.githubusercontent.com on EVERY job —
# a transient fetch failure fails the whole job (2026-07-28 slice-5
# incident). Pinned, the binary downloads directly; no manifest hop.
version: "0.9.28"
version: '0.9.28'
enable-cache: true
cache-dependency-glob: |
pyproject.toml
@@ -106,11 +111,11 @@ jobs:
npx playwright test --reporter=list
fi
env:
CI: "true"
CI: 'true'
# Ensure no real API keys leak into the test env.
OPENROUTER_API_KEY: ""
OPENAI_API_KEY: ""
NOUS_API_KEY: ""
OPENROUTER_API_KEY: ''
OPENAI_API_KEY: ''
NOUS_API_KEY: ''
# ── Save updated baselines to cache (main only) ───────────────────
- name: Save updated baselines to cache

View File

@@ -70,6 +70,10 @@ jobs:
node-version: 22
cache: npm
- name: grab npm 12
run: |
npm i -g npm@12
# --ignore-scripts: eslint only needs TS sources + eslint packages.
- uses: ./.github/actions/retry
with:

View File

@@ -17,6 +17,11 @@ jobs:
with:
node-version: 22
cache: npm
- name: grab npm 12
run: |
npm i -g npm@12
- uses: ./.github/actions/retry
with:
command: npm ci --ignore-scripts
@@ -63,6 +68,11 @@ jobs:
with:
node-version: 22
cache: npm
- name: grab npm 12
run: |
npm i -g npm@12
- uses: ./.github/actions/retry
with:
command: npm ci

4
.npmrc
View File

@@ -45,3 +45,7 @@ min-release-age-exclude[]=vite
min-release-age-exclude[]=rolldown
min-release-age-exclude[]=@rolldown/*
min-release-age-exclude[]=@oxc-project/types
# ink needs
min-release-age-exclude[]=lightningcss
min-release-age-exclude[]=postcss

View File

@@ -19,7 +19,7 @@
"fix": "npm run lint:fix"
},
"dependencies": {
"@nous-research/ui": "0.16.0",
"@nous-research/ui": "0.18.2",
"@tailwindcss/typography": "0.5.20",
"@tailwindcss/vite": "4.3.3",
"@tauri-apps/api": "2.11.1",

View File

@@ -81,7 +81,7 @@
"@icons-pack/react-simple-icons": "13.11.1",
"@lezer/highlight": "1.2.3",
"@nanostores/react": "1.1.0",
"@nous-research/ui": "0.16.0",
"@nous-research/ui": "0.18.2",
"@streamdown/code": "1.1.1",
"@tabler/icons-react": "3.44.0",
"@tailwindcss/typography": "0.5.20",

0
log.txt Normal file
View File

View File

@@ -17,18 +17,6 @@
...
}:
let
# apps/shared ships as a file: workspace dep of apps/desktop, so its
# source must be in the filtered src tree too.
npm = hermesNpmLib.mkNpmPassthru {
dirs = [
"apps/desktop"
"apps/shared"
];
};
packageJson = builtins.fromJSON (builtins.readFile (npm.src + "/apps/desktop/package.json"));
version = packageJson.version;
electronHeaders = pkgs.fetchurl {
url = "https://artifacts.electronjs.org/headers/dist/v${electron.version}/node-v${electron.version}-headers.tar.gz";
sha256 = "sha256-f8bSbLRmtbP93CJAvEBs+sHWDZ1xP2bcpLhC1EnOmZU=";
@@ -54,99 +42,101 @@ let
throw "hermes-desktop: unsupported host arch for node-pty staging";
# Build the renderer (dist/ + electron/ + package.json).
renderer = pkgs.buildNpmPackage (
npm
// {
pname = "hermes-desktop-renderer";
inherit version;
doCheck = true;
renderer = hermesNpmLib.buildNpmPackage {
dirs = [
"apps/desktop"
"apps/shared"
];
pname = "hermes-desktop-renderer";
buildPhase = ''
runHook preBuild
doCheck = true;
mkdir -p apps/desktop/build
buildPhase = ''
runHook preBuild
patchShebangs .
mkdir -p apps/desktop/build
pushd apps/desktop
# typecheck :3
npm exec tsc -b
patchShebangs .
# build the renderer bundle
# vite's emptyOutDir wipes dist/ on every run
# so it has to be first
npm exec vite build
pushd apps/desktop
# typecheck :3
npm exec -- tsc -b
# build the electron bundle
node scripts/bundle-electron-main.mjs
# build the renderer bundle
# vite's emptyOutDir wipes dist/ on every run
# so it has to be first
npm exec -- vite build
# Compile node-pty against Electron's actual ABI (the nixpkgs
# `electron` we ship). Headers come from a pinned fetchurl input
# since the sandbox has no network here, so node-gyp's
# normal --disturl download path can't run.
mkdir -p "$TMPDIR/electron-headers"
tar -xzf ${electronHeaders} -C "$TMPDIR/electron-headers" --strip-components=1
# build the electron bundle
node scripts/bundle-electron-main.mjs
npm rebuild node-pty \
--build-from-source \
--runtime=electron \
--target=${electron.version} \
--nodedir="$TMPDIR/electron-headers" \
--disturl="" \
--offline
# Compile node-pty against Electron's actual ABI (the nixpkgs
# `electron` we ship). Headers come from a pinned fetchurl input
# since the sandbox has no network here, so node-gyp's
# normal --disturl download path can't run.
mkdir -p "$TMPDIR/electron-headers"
tar -xzf ${electronHeaders} -C "$TMPDIR/electron-headers" --strip-components=1
# Target platform/arch come from stdenv.hostPlatform, not the
# build host's own process.platform/arch.
node scripts/stage-native-deps.mjs ${targetPlatform} ${targetArch}
popd
${lib.getExe hermesNpmLib.node-gyp} rebuild \
--directory=../../node_modules/node-pty \
--build-from-source \
--runtime=electron \
--target=${electron.version} \
--nodedir="$TMPDIR/electron-headers" \
--disturl="" \
--offline
runHook postBuild
'';
# Target platform/arch come from stdenv.hostPlatform, not the
# build host's own process.platform/arch.
node scripts/stage-native-deps.mjs ${targetPlatform} ${targetArch}
popd
checkPhase = ''
runHook preCheck
runHook postBuild
'';
pushd apps/desktop
checkPhase = ''
runHook preCheck
npm run postbuild
pushd apps/desktop
# validate staged node-pty native binary is present.
STAGED_PTY_NODE="./dist/node_modules/node-pty/build/Release/pty.node"
npm run postbuild
if [ ! -f "$STAGED_PTY_NODE" ]; then
echo "FATAL: Missing staged node-pty native binary at $STAGED_PTY_NODE"
echo "node-pty must be compiled natively"
exit 1
fi
popd
# validate staged node-pty native binary is present.
STAGED_PTY_NODE="./dist/node_modules/node-pty/build/Release/pty.node"
runHook postCheck
'';
if [ ! -f "$STAGED_PTY_NODE" ]; then
echo "FATAL: Missing staged node-pty native binary at $STAGED_PTY_NODE"
echo "node-pty must be compiled natively"
exit 1
fi
popd
installPhase = ''
runHook preInstall
mkdir -p $out
# vite writes to apps/desktop/dist/ (we cd'd there in buildPhase).
# stage-native-deps.mjs stages node-pty into dist/node_modules/node-pty,
# so copying dist/ wholesale carries the native dep along with the
# esbuild bundle that require()s it. apps/desktop/build was created
# before the cd.
cp -rn apps/desktop/dist $out/
runHook postCheck
'';
echo '{"schemaVersion":1,"commit":"nix-dummy-commit","branch":"nix","dirty":false,"source":"nix"}' > $out/install-stamp.json
installPhase = ''
runHook preInstall
mkdir -p $out
# vite writes to apps/desktop/dist/ (we cd'd there in buildPhase).
# stage-native-deps.mjs stages node-pty into dist/node_modules/node-pty,
# so copying dist/ wholesale carries the native dep along with the
# esbuild bundle that require()s it. apps/desktop/build was created
# before the cd.
cp -rn apps/desktop/dist $out/
cp -n apps/desktop/package.json $out/
runHook postInstall
'';
}
);
echo '{"schemaVersion":1,"commit":"nix-dummy-commit","branch":"nix","dirty":false,"source":"nix"}' > $out/install-stamp.json
cp -n apps/desktop/package.json $out/
runHook postInstall
'';
};
in
# Electron wrapper: nixpkgs' electron binary pointed at the renderer dir.
stdenv.mkDerivation {
pname = "hermes-desktop";
inherit version;
inherit (renderer) version;
dontUnpack = true;
dontBuild = true;

View File

@@ -10,7 +10,6 @@
makeWrapper,
callPackage,
python312,
nodejs_26,
electron,
ripgrep,
git,
@@ -39,7 +38,6 @@
extraDependencyGroups ? [ ],
}:
let
nodejs = nodejs_26;
mkHermesVenv =
extraDependencyGroups:
callPackage ./python.nix {
@@ -51,7 +49,7 @@ let
hermesVenv = (mkHermesVenv extraDependencyGroups).venv;
hermesNpmLib = callPackage ./lib.nix {
inherit npm-lockfile-fix nodejs;
inherit npm-lockfile-fix;
};
hermesTui = callPackage ./tui.nix {
@@ -97,7 +95,7 @@ let
};
runtimeDeps = [
nodejs
hermesNpmLib.nodejs
ripgrep
git
openssh
@@ -195,7 +193,7 @@ stdenv.mkDerivation (finalAttrs: {
--set HERMES_WEB_DIST $out/share/hermes-agent/web_dist \
--set HERMES_TUI_DIR $out/ui-tui \
--set HERMES_PYTHON ${hermesVenv}/bin/python3 \
--set HERMES_NODE ${lib.getExe nodejs}${
--set HERMES_NODE ${lib.getExe hermesNpmLib.nodejs}${
# Fold the line continuation INTO the optionalString: a bare
# `\` on the line above an empty expansion would dangle onto a
# blank line, ending the makeWrapper command early and running

View File

@@ -18,13 +18,46 @@
# root to update the lockfile, then `npm ci` if the lockfile changed.
{
lib,
pkgs,
npm-lockfile-fix,
nodejs,
importNpmLock,
writeShellScriptBin,
writeShellScript,
coreutils,
callPackage,
nodejs_26,
symlinkJoin,
buildNpmPackage,
runCommand,
}:
let
repoRoot = ./..;
npm12 = callPackage ./npm-12-0-2.nix { };
node_gyp_11_4_0 = callPackage ./node-gyp-11-4-0.nix { };
nodejs_26_npm_12 = symlinkJoin {
name = "nodejs-26-npm-12";
paths = [
npm12
nodejs_26
];
inherit (nodejs_26) meta passthru;
};
nodejs = nodejs_26_npm_12;
# Patched hook: just a new derivation that copies and patches the script
patchedNpmConfigHook = runCommand "npm-config-hook-patched" { } ''
mkdir -p $out/nix-support
# Copy all support files from the original hook
cp -r ${importNpmLock.npmConfigHook}/nix-support/* $out/nix-support/
# Change the node gyp config var to avoid the warning with npm12
# Replace the node-gyp path with the newer one that supports the new config var
substituteInPlace $out/nix-support/setup-hook \
--replace-fail 'npm_config_nodedir' 'npm_package_config_node_gyp_nodedir' \
--replace-fail 'npm_config_node_gyp' 'npm_config_node_gyp=${node_gyp_11_4_0}/bin/node-gyp'
'';
# ── npm workspace discovery ────────────────────────────────────────
# Single source of truth: the `workspaces` field of the root
# package.json. Everything below (workspace package.json discovery,
@@ -62,7 +95,9 @@ let
# Top-level directory of each workspace member, deduplicated. Used to
# exclude JS/TS workspace trees from the Python source filter. E.g.
# apps/desktop + apps/shared + ui-tui + web → [ "apps" "ui-tui" "web" ].
jsWorkspaceTopDirs = lib.unique (map (d: builtins.head (lib.splitString "/" d)) workspaceMemberDirs);
jsWorkspaceTopDirs = lib.unique (
map (d: builtins.head (lib.splitString "/" d)) workspaceMemberDirs
);
# ── Source filters for reducing rebuild scope ──────────────────────
# Changing a .tsx/.mjs file should NOT trigger a Python venv rebuild,
@@ -82,8 +117,7 @@ let
# JS/TS workspace directories — derived from the npm workspaces
# so a new workspace member is excluded from the Python source
# without touching this list.
jsWorkspaceTopDirs
++ [
jsWorkspaceTopDirs ++ [
# Documentation
"docs"
"website"
@@ -173,7 +207,9 @@ let
# resolves each package from the lockfile's own `integrity` hashes, so the
# lockfile is the single source of truth — no separate dependency hash to
# keep in sync with it.
npmDeps = pkgs.importNpmLock.importNpmLock { npmRoot = npmDepsSrc; };
npmDeps = importNpmLock.importNpmLock {
npmRoot = npmDepsSrc;
};
# Build a per-package npm source: workspace resolution files + the
# package's own directory tree(s). Source ROOT is always the repo
@@ -188,16 +224,70 @@ let
lib.fileset.unions (map (d: repoRoot + "/${d}") dirs)
);
};
# Returns a buildNpmPackage-compatible function.
# `dirs` is the single source of truth for what the package contains:
# its first entry is the package's own folder (→ packageJsonPath), and
# all entries scope the filtered src. Packages that import source from
# another workspace member (file: deps) must list that member's dir too,
# e.g. apps/desktop depends on apps/shared.
#
# Usage:
# hermesNpmLib.buildNpmPackage {
# dirs = [ "apps/desktop" "apps/shared" ];
# buildPhase = '' ... '';
# installPhase = '' ... '';
# }
customBuildNpmPackage =
{ dirs, ... }@attrs:
let
# The package's own folder is the first dir; it carries the
# package.json that buildNpmPackage reads.
folder = builtins.head dirs;
# Read package.json from the repo (the filtered src is a store path, but we can read the original)
packageJson = builtins.fromJSON (builtins.readFile (repoRoot + "/${folder}/package.json"));
defaultPname = packageJson.name or "unknown";
defaultVersion = packageJson.version or "0.0.0";
common = {
inherit nodejs npmDeps;
# No sourceRoot — the workspace root (with the single package-lock.json)
# is auto-detected as sourceRoot by nix. npmRoot stays at "."
# so npmConfigHook finds the lockfile there.
src = mkNpmSrc dirs;
npmConfigHook = patchedNpmConfigHook;
npmRoot = ".";
ELECTRON_SKIP_BINARY_DOWNLOAD = 1;
passthru = {
packageJsonPath = "${folder}/package.json";
};
};
# Remove `dirs` from the passed attrs (buildNpmPackage doesn't need it)
attrsWithoutDirs = removeAttrs attrs [ "dirs" ];
finalAttrs =
common
// attrsWithoutDirs
// {
pname = attrs.pname or defaultPname;
version = attrs.version or defaultVersion;
};
in
buildNpmPackage finalAttrs;
in
{
inherit pythonSrc;
inherit pythonSrc nodejs;
node-gyp = node_gyp_11_4_0;
# Regenerate the shared root lockfile from scratch and verify all npm
# packages still build. Exposed as a runnable package — `nix run
# .#update-npm-lockfile` — so it's actually usable, unlike a bin buried
# in a build sandbox's PATH. All workspace packages share one lockfile,
# so there's a single script (not one per package).
updateNpmLockfile = pkgs.writeShellScriptBin "update-npm-lockfile" ''
updateNpmLockfile = writeShellScriptBin "update-npm-lockfile" ''
set -euo pipefail
# DEBUG=1 nix run .#update-npm-lockfile trace every command
[ -n "''${DEBUG:-}" ] && set -x
@@ -206,9 +296,9 @@ in
cd "$REPO_ROOT"
rm -rf node_modules/
${pkgs.lib.getExe' nodejs "npm"} cache clean --force
CI=true ${pkgs.lib.getExe' nodejs "npm"} install --workspaces
${pkgs.lib.getExe npm-lockfile-fix} ./package-lock.json
${lib.getExe' nodejs "npm"} cache clean --force
CI=true ${lib.getExe' nodejs "npm"} install --workspaces
${lib.getExe npm-lockfile-fix} ./package-lock.json
# importNpmLock reads hashes from the lockfile itself rebuild every
# npm package to verify the new lockfile resolves offline.
@@ -216,53 +306,7 @@ in
echo "Lockfile updated and all npm packages built."
'';
# Returns a buildNpmPackage-compatible attrs set that provides:
# src, npmDeps, npmRoot — filtered workspace source + importNpmLock dep set
# npmConfigHook — importNpmLock's offline `npm install` hook
# passthru.packageJsonPath — relative path to this workspace's package.json
# nodejs — fixed nodejs version for all packages we use in the repo
#
# `dirs` is the single source of truth for what the package contains:
# its first entry is the package's own folder (→ packageJsonPath), and
# all entries scope the filtered src. Packages that import source from
# another workspace member (file: deps) must list that member's dir too,
# e.g. apps/desktop depends on apps/shared.
#
# Usage:
# npm = hermesNpmLib.mkNpmPassthru { dirs = [ "ui-tui" ]; };
# npm = hermesNpmLib.mkNpmPassthru { dirs = [ "apps/desktop" "apps/shared" ]; };
# pkgs.buildNpmPackage (npm // {
# pname = "hermes-tui";
# inherit version;
# buildPhase = '' ... '';
# installPhase = '' ... '';
# })
mkNpmPassthru =
{ dirs }:
let
# The package's own folder is the first dir; it carries the
# package.json that buildNpmPackage reads.
folder = builtins.head dirs;
# No sourceRoot — the workspace root (with the single package-lock.json)
# is auto-detected as sourceRoot by nix. npmRoot stays at "."
# so npmConfigHook finds the lockfile there.
in
{
inherit nodejs npmDeps;
src = mkNpmSrc dirs;
# importNpmLock's hook installs the rewritten lockfile (every `resolved`
# rewritten to a /nix/store file: path) into the unpacked workspace and
# runs `npm install` offline, so every workspace member's dependencies
# resolve without network access.
npmConfigHook = pkgs.importNpmLock.npmConfigHook;
npmRoot = ".";
ELECTRON_SKIP_BINARY_DOWNLOAD = 1;
passthru = {
packageJsonPath = "${folder}/package.json";
};
};
buildNpmPackage = customBuildNpmPackage;
# Single devshell hook for all npm workspace packages.
#
@@ -272,23 +316,23 @@ in
# 2. If the lockfile changed, runs `npm ci`
mkNpmDevShellHook =
packageJsonPaths:
pkgs.writeShellScript "npm-dev-hook" ''
writeShellScript "npm-dev-hook" ''
REPO_ROOT=$(git rev-parse --show-toplevel)
# Stamp all workspace package.jsons into one file.
STAMP_DIR=".nix-stamps"
STAMP="$STAMP_DIR/npm-package-jsons"
STAMP_VALUE=$(
${pkgs.coreutils}/bin/sha256sum ${
pkgs.lib.concatMapStringsSep " " (p: "\"$REPO_ROOT/${p}\"") packageJsonPaths
} 2>/dev/null | ${pkgs.coreutils}/bin/sort | ${pkgs.coreutils}/bin/sha256sum | awk '{print $1}'
${coreutils}/bin/sha256sum ${
lib.concatMapStringsSep " " (p: "\"$REPO_ROOT/${p}\"") packageJsonPaths
} 2>/dev/null | ${coreutils}/bin/sort | ${coreutils}/bin/sha256sum | awk '{print $1}'
)
PKG_CHANGED=false
if [ ! -f "$STAMP" ] || [ "$(cat "$STAMP")" != "$STAMP_VALUE" ]; then
PKG_CHANGED=true
echo "npm: package.json changed, updating lockfile..."
( cd "$REPO_ROOT" && ${pkgs.lib.getExe' nodejs "npm"} i --package-lock-only --silent --no-fund --no-audit 2>/dev/null )
( cd "$REPO_ROOT" && ${lib.getExe' nodejs "npm"} i --package-lock-only --silent --no-fund --no-audit 2>/dev/null )
mkdir -p "$STAMP_DIR"
echo "$STAMP_VALUE" > "$STAMP"
fi
@@ -299,7 +343,7 @@ in
LOCK_STAMP_VALUE=$(sha256sum "$REPO_ROOT/package-lock.json" 2>/dev/null | awk '{print $1}')
if [ ! -f "$LOCK_STAMP" ] || [ "$(cat "$LOCK_STAMP")" != "$LOCK_STAMP_VALUE" ]; then
echo "npm: package-lock.json changed, running npm ci..."
( cd "$REPO_ROOT" && CI=true ${pkgs.lib.getExe' nodejs "npm"} ci --silent --no-fund --no-audit 2>/dev/null )
( cd "$REPO_ROOT" && CI=true ${lib.getExe' nodejs "npm"} ci --silent --no-fund --no-audit 2>/dev/null )
mkdir -p "$STAMP_DIR"
echo "$LOCK_STAMP_VALUE" > "$LOCK_STAMP"
fi

5246
nix/node-gyp-11-4-0-package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

40
nix/node-gyp-11-4-0.nix Normal file
View File

@@ -0,0 +1,40 @@
{
buildNpmPackage,
fetchFromGitHub,
nodejs,
lib,
}:
let
node-gyp-11_4_0 = buildNpmPackage rec {
pname = "node-gyp";
version = "11.4.0";
src = fetchFromGitHub {
owner = "nodejs";
repo = "node-gyp";
rev = "refs/tags/v${version}";
hash = "sha256-VtomUV+0kTp34IuS0D0dR4ZMWpk4Ptpk1CBP8rdW2a4=";
};
postPatch = ''
ln -s ${./node-gyp-11-4-0-package-lock.json} package-lock.json
'';
npmDepsHash = "sha256-P25m02VxIXkPD7rYI2Wki9+levrtNg2xk8pU+nEUXsE=";
npmDepsFetcherVersion = 2;
dontNpmBuild = true;
makeWrapperArgs = [ "--set npm_config_nodedir ${nodejs}" ];
meta = {
description = "Node.js native addon build tool";
homepage = "https://github.com/nodejs/node-gyp";
license = lib.licenses.mit;
mainProgram = "node-gyp";
};
};
in
node-gyp-11_4_0

29
nix/npm-12-0-2.nix Normal file
View File

@@ -0,0 +1,29 @@
{
stdenv,
makeWrapper,
fetchurl,
nodejs_26,
}:
stdenv.mkDerivation rec {
pname = "npm";
version = "12.0.2";
src = fetchurl {
url = "https://registry.npmjs.org/npm/-/npm-${version}.tgz";
hash = "sha256-XbuGxx0HoZV/LpBzQJLdali9zZ68LY1ByhxuaiHTZOE=";
};
nativeBuildInputs = [ makeWrapper ];
dontBuild = true;
installPhase = ''
mkdir -p $out/lib/npm12
cp -r . $out/lib/npm12/
mkdir -p $out/bin
makeWrapper ${nodejs_26}/bin/node $out/bin/npm \
--add-flags "$out/lib/npm12/bin/npm-cli.js"
makeWrapper ${nodejs_26}/bin/node $out/bin/npx \
--add-flags "$out/lib/npm12/bin/npx-cli.js"
'';
}

View File

@@ -45,6 +45,10 @@
in
{
packages = {
node-gyp =
(pkgs.callPackage ./lib.nix {
inherit (pkgs) npm-lockfile-fix;
}).node-gyp;
default = full;
inherit minimal;

View File

@@ -1,19 +1,10 @@
# nix/tui.nix — Hermes TUI (Ink/React) compiled with tsc and bundled
{ pkgs, hermesNpmLib, ... }:
let
npm = hermesNpmLib.mkNpmPassthru {
dirs = [
"ui-tui"
"apps/shared"
];
};
packageJson = builtins.fromJSON (builtins.readFile (npm.src + "/ui-tui/package.json"));
version = packageJson.version;
in
pkgs.buildNpmPackage (npm // {
pname = "hermes-tui";
inherit version;
{ hermesNpmLib, ... }:
hermesNpmLib.buildNpmPackage {
dirs = [
"ui-tui"
"apps/shared"
];
doCheck = false;
@@ -35,4 +26,4 @@ pkgs.buildNpmPackage (npm // {
runHook postInstall
'';
})
}

View File

@@ -1,21 +1,13 @@
# nix/web.nix — Hermes Web Dashboard (Vite/React) frontend build
{ pkgs, hermesNpmLib, ... }:
let
# @hermes/shared ships as a file: workspace dep of web, so its source
# must be in the filtered src tree too.
npm = hermesNpmLib.mkNpmPassthru {
dirs = [
"web"
"apps/shared"
];
};
{ hermesNpmLib, ... }:
hermesNpmLib.buildNpmPackage {
dirs = [
"web"
packageJson = builtins.fromJSON (builtins.readFile (npm.src + "/web/package.json"));
version = packageJson.version;
in
pkgs.buildNpmPackage (npm // {
pname = "hermes-web";
inherit version;
# @hermes/shared ships as a file: workspace dep of web, so its source
# must be in the filtered src tree too.
"apps/shared"
];
doCheck = false;
@@ -38,4 +30,4 @@ pkgs.buildNpmPackage (npm // {
cp -r web/dist $out
runHook postInstall
'';
})
}

3929
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -54,7 +54,7 @@
},
"engines": {
"node": ">=20.0.0",
"npm": "<11.10.0 || >=12.0.0"
"npm": ">=12.0.0"
},
"allowScripts": {
"unicode-animations": false,

View File

@@ -22,13 +22,17 @@
"@hermes/ink": "file:./packages/hermes-ink",
"@hermes/shared": "file:../apps/shared",
"@nanostores/react": "1.1.0",
"ink": "6.8.0",
"ink-text-input": "6.0.0",
"nanostores": "1.4.0",
"react": "19.2.7",
"undici": "6.27.0",
"unicode-animations": "1.0.3"
},
"overrides": {
"ink-text-input": {
"ink": "npm:@hermes/ink@0.0.1"
}
},
"devDependencies": {
"@types/node": "22.20.1",
"@types/react": "19.2.17",

View File

@@ -16,7 +16,7 @@
},
"dependencies": {
"@hermes/shared": "file:../apps/shared",
"@nous-research/ui": "0.16.0",
"@nous-research/ui": "0.18.2",
"@observablehq/plot": "0.6.17",
"@react-three/fiber": "9.6.1",
"@tailwindcss/vite": "4.3.3",