Compare commits

...

6 Commits

Author SHA1 Message Date
github-actions[bot]
847cf0335a fix(nix): refresh npm lockfile hashes 2026-04-30 15:45:16 +00:00
ethernet
3ac5a6b474 add some random pkg to trigger ci fail 2026-04-30 11:40:13 -04:00
ethernet
d79cbb7763 fix(nix): update lock files yet again (hopefully for the last time) 2026-04-30 11:20:43 -04:00
ethernet
cdda9847cd fix(nix): use same nodejs version everywhere & small lints
- prevent lockfile thrashing while using nix :3
- use lib.getExe instead of raw /bin/ paths
- use inputs'.self instead of passing system in manually
2026-04-30 11:20:43 -04:00
ethernet
978c0aed85 feat(nix): make .#fix-lockfiles run --apply if no args passed 2026-04-30 11:20:43 -04:00
ethernet
f4745a2c72 change(nix): dedupe nix lockfile checking scripts in ci 2026-04-30 11:20:43 -04:00
11 changed files with 223 additions and 172 deletions

View File

@@ -1,76 +0,0 @@
name: Nix Lockfile Check
on:
pull_request:
workflow_dispatch:
permissions:
contents: read
pull-requests: write
concurrency:
group: nix-lockfile-check-${{ github.ref }}
cancel-in-progress: true
jobs:
nix-lockfile-check:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: ./.github/actions/nix-setup
with:
cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}
- name: Resolve head SHA
id: sha
shell: bash
run: |
FULL="${{ github.event.pull_request.head.sha || github.sha }}"
echo "full=$FULL" >> "$GITHUB_OUTPUT"
echo "short=${FULL:0:7}" >> "$GITHUB_OUTPUT"
- name: Check lockfile hashes
id: check
continue-on-error: true
env:
LINK_SHA: ${{ steps.sha.outputs.full }}
run: nix run .#fix-lockfiles -- --check
- name: Fail if check crashed without reporting
if: steps.check.outputs.stale != 'true' && steps.check.outputs.stale != 'false'
run: |
echo "::error::fix-lockfiles exited without reporting stale status — likely an infrastructure or script failure"
exit 1
- name: Post sticky PR comment (stale)
if: steps.check.outputs.stale == 'true' && github.event_name == 'pull_request'
uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2.9.1
with:
header: nix-lockfile-check
message: |
### ⚠️ npm lockfile hash out of date
Checked against commit [`${{ steps.sha.outputs.short }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ steps.sha.outputs.full }}) (PR head at check time).
The `hash = "sha256-..."` line in these nix files no longer matches the committed `package-lock.json`:
${{ steps.check.outputs.report }}
#### Apply the fix
- [ ] **Apply lockfile fix** — tick to push a commit with the correct hashes to this PR branch
- Or [run the Nix Lockfile Fix workflow](${{ github.server_url }}/${{ github.repository }}/actions/workflows/nix-lockfile-fix.yml) manually (pass PR `#${{ github.event.pull_request.number }}`)
- Or locally: `nix run .#fix-lockfiles -- --apply` and commit the diff
- name: Clear sticky PR comment (resolved)
if: steps.check.outputs.stale == 'false' && github.event_name == 'pull_request'
uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2.9.1
with:
header: nix-lockfile-check
delete: true
- name: Fail if stale
if: steps.check.outputs.stale == 'true'
run: exit 1

View File

@@ -28,7 +28,7 @@ concurrency:
jobs: jobs:
# ── Auto-fix on main ─────────────────────────────────────────────── # ── Auto-fix on main ───────────────────────────────────────────────
# Fires when a push to main touches package.json or package-lock.json # Fires when a push to main touches package.json or package-lock.json
# in ui-tui/ or web/. Runs fix-lockfiles --apply and pushes the hash # in ui-tui/ or web/. Runs fix-lockfiles and pushes the hash
# update commit directly to main so Nix builds never stay broken. # update commit directly to main so Nix builds never stay broken.
# #
# Safety invariants: # Safety invariants:
@@ -207,7 +207,7 @@ jobs:
- name: Apply lockfile hashes - name: Apply lockfile hashes
id: apply id: apply
run: nix run .#fix-lockfiles -- --apply run: nix run .#fix-lockfiles
- name: Commit & push - name: Commit & push
if: steps.apply.outputs.changed == 'true' if: steps.apply.outputs.changed == 'true'

View File

@@ -7,6 +7,7 @@ on:
permissions: permissions:
contents: read contents: read
pull-requests: write
concurrency: concurrency:
group: nix-${{ github.ref }} group: nix-${{ github.ref }}
@@ -24,12 +25,93 @@ jobs:
- uses: ./.github/actions/nix-setup - uses: ./.github/actions/nix-setup
with: with:
cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}
- name: Resolve head SHA
if: github.event_name == 'pull_request'
id: sha
shell: bash
run: |
FULL="${{ github.event.pull_request.head.sha || github.sha }}"
echo "full=$FULL" >> "$GITHUB_OUTPUT"
echo "short=${FULL:0:7}" >> "$GITHUB_OUTPUT"
- name: Check flake - name: Check flake
id: flake
if: runner.os == 'Linux' if: runner.os == 'Linux'
continue-on-error: true
run: nix flake check --print-build-logs run: nix flake check --print-build-logs
- name: Build package - name: Build package
id: build
if: runner.os == 'Linux' if: runner.os == 'Linux'
continue-on-error: true
run: nix build --print-build-logs run: nix build --print-build-logs
# When the real Nix build fails, run a targeted diagnostic to see if
# the failure is specifically a stale npm lockfile hash in one of the
# known npm subpackages (tui / web). This avoids surfacing a generic
# "build failed" message when the fix is a single known command.
- name: Diagnose npm lockfile hashes
id: hash_check
if: (steps.flake.outcome == 'failure' || steps.build.outcome == 'failure') && runner.os == 'Linux'
continue-on-error: true
env:
LINK_SHA: ${{ steps.sha.outputs.full }}
run: nix run .#fix-lockfiles -- --check
# If fix-lockfiles itself crashes (infrastructure blip, cache throttle,
# etc.) it won't set stale=true/false. Treat that as a distinct failure
# mode rather than silently ignoring it.
- name: Fail if hash check crashed without reporting
if: steps.hash_check.outcome == 'failure' && steps.hash_check.outputs.stale != 'true' && steps.hash_check.outputs.stale != 'false'
run: |
echo "::error::fix-lockfiles exited without reporting stale status — likely an infrastructure or script failure"
exit 1
- name: Post sticky PR comment (stale hashes)
if: steps.hash_check.outputs.stale == 'true' && github.event_name == 'pull_request'
uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2.9.1
with:
header: nix-lockfile-check
message: |
### ⚠️ npm lockfile hash out of date
Checked against commit [`${{ steps.sha.outputs.short }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ steps.sha.outputs.full }}) (PR head at check time).
The `hash = "sha256-..."` line in these nix files no longer matches the committed `package-lock.json`:
${{ steps.hash_check.outputs.report }}
#### Apply the fix
- [ ] **Apply lockfile fix** — tick to push a commit with the correct hashes to this PR branch
- Or [run the Nix Lockfile Fix workflow](${{ github.server_url }}/${{ github.repository }}/actions/workflows/nix-lockfile-fix.yml) manually (pass PR `#${{ github.event.pull_request.number }}`)
- Or locally: `nix run .#fix-lockfiles` and commit the diff
# Clear the sticky comment when either the build passed outright (no
# hash check needed) or the hash check explicitly returned stale=false
# (build failed for a non-hash reason).
- name: Clear sticky PR comment (resolved)
if: |
github.event_name == 'pull_request' &&
runner.os == 'Linux' &&
(steps.hash_check.outputs.stale == 'false' ||
(steps.flake.outcome == 'success' && steps.build.outcome == 'success'))
uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2.9.1
with:
header: nix-lockfile-check
delete: true
- name: Final fail if build or flake failed
if: steps.flake.outcome == 'failure' || steps.build.outcome == 'failure'
run: |
if [ "${{ steps.hash_check.outputs.stale }}" == "true" ]; then
echo "::error::Nix build failed due to stale npm lockfile hash. Run: nix run .#fix-lockfiles"
else
echo "::error::Nix build/flake check failed. See logs above."
fi
exit 1
- name: Evaluate flake (macOS) - name: Evaluate flake (macOS)
if: runner.os == 'macOS' if: runner.os == 'macOS'
run: nix flake show --json > /dev/null run: nix flake show --json > /dev/null

View File

@@ -4,9 +4,9 @@
# transitive deps like onnxruntime that lack compatible wheels on # transitive deps like onnxruntime that lack compatible wheels on
# aarch64-darwin. The package and devShell still work on macOS. # aarch64-darwin. The package and devShell still work on macOS.
{ inputs, ... }: { { inputs, ... }: {
perSystem = { pkgs, system, lib, ... }: perSystem = { pkgs, lib, self', ... }:
let let
hermes-agent = inputs.self.packages.${system}.default; hermes-agent = self'.packages.default;
hermesVenv = hermes-agent.hermesVenv; hermesVenv = hermes-agent.hermesVenv;
configMergeScript = pkgs.callPackage ./configMergeScript.nix { }; configMergeScript = pkgs.callPackage ./configMergeScript.nix { };
@@ -51,7 +51,7 @@ json.dump(sorted(leaf_paths(DEFAULT_CONFIG)), sys.stdout, indent=2)
failMsg = lib.concatMapStringsSep "\n" (r: " - ${r.sys}") failures; failMsg = lib.concatMapStringsSep "\n" (r: " - ${r.sys}") failures;
in pkgs.runCommand "hermes-cross-eval" { } ( in pkgs.runCommand "hermes-cross-eval" { } (
if failures != [] then if failures != [] then
builtins.throw "Package fails to evaluate on:\n${failMsg}" throw "Package fails to evaluate on:\n${failMsg}"
else '' else ''
echo "PASS: package evaluates on all ${toString (builtins.length targetSystems)} platforms" echo "PASS: package evaluates on all ${toString (builtins.length targetSystems)} platforms"
mkdir -p $out mkdir -p $out

View File

@@ -1,25 +1,26 @@
# nix/devShell.nix — Dev shell that delegates setup to each package # nix/devShell.nix — Dev shell that delegates setup to each package
# #
# Each package in inputsFrom exposes passthru.devShellHook — a bash snippet # Each package in inputsFrom might expose passthru.devShellHook — a bash snippet
# with stamp-checked setup logic. This file collects and runs them all. # with stamp-checked setup logic. This file collects and runs them all.
{ inputs, ... }: { { ... }:
perSystem = { pkgs, system, ... }: {
perSystem =
{ pkgs, self', ... }:
let let
hermes-agent = inputs.self.packages.${system}.default; packages = builtins.attrValues self'.packages;
hermes-tui = inputs.self.packages.${system}.tui; in
hermes-web = inputs.self.packages.${system}.web; {
packages = [ hermes-agent hermes-tui hermes-web ];
in {
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
inputsFrom = packages; inputsFrom = packages;
packages = with pkgs; [ packages = with pkgs; [
python312 uv nodejs_22 ripgrep git openssh ffmpeg uv
]; ];
shellHook =
shellHook = let let
hooks = map (p: p.passthru.devShellHook or "") packages; hooks = map (p: p.passthru.devShellHook or "") packages;
combined = pkgs.lib.concatStringsSep "\n" (builtins.filter (h: h != "") hooks); combined = pkgs.lib.concatStringsSep "\n" (builtins.filter (h: h != "") hooks);
in '' in
''
echo "Hermes Agent dev shell" echo "Hermes Agent dev shell"
${combined} ${combined}
echo "Ready. Run 'hermes' to start." echo "Ready. Run 'hermes' to start."

View File

@@ -27,12 +27,13 @@
extraPythonPackages ? [ ], extraPythonPackages ? [ ],
}: }:
let let
nodejs = nodejs_22;
hermesVenv = callPackage ./python.nix { hermesVenv = callPackage ./python.nix {
inherit uv2nix pyproject-nix pyproject-build-systems; inherit uv2nix pyproject-nix pyproject-build-systems;
}; };
hermesNpmLib = callPackage ./lib.nix { hermesNpmLib = callPackage ./lib.nix {
inherit npm-lockfile-fix; inherit npm-lockfile-fix nodejs;
}; };
hermesTui = callPackage ./tui.nix { hermesTui = callPackage ./tui.nix {
@@ -57,7 +58,7 @@ let
}; };
runtimeDeps = [ runtimeDeps = [
nodejs_22 nodejs
ripgrep ripgrep
git git
openssh openssh
@@ -82,49 +83,7 @@ let
builtins.hashString "sha256" (builtins.readFile ../uv.lock) builtins.hashString "sha256" (builtins.readFile ../uv.lock)
else else
"none"; "none";
in checkPackageCollisions = ''
stdenv.mkDerivation {
pname = "hermes-agent";
version = (builtins.fromTOML (builtins.readFile ../pyproject.toml)).project.version;
dontUnpack = true;
dontBuild = true;
nativeBuildInputs = [ makeWrapper ];
installPhase = ''
runHook preInstall
mkdir -p $out/share/hermes-agent $out/bin
cp -r ${bundledSkills} $out/share/hermes-agent/skills
cp -r ${bundledPlugins} $out/share/hermes-agent/plugins
cp -r ${hermesWeb} $out/share/hermes-agent/web_dist
mkdir -p $out/ui-tui
cp -r ${hermesTui}/lib/hermes-tui/* $out/ui-tui/
${lib.concatMapStringsSep "\n"
(name: ''
makeWrapper ${hermesVenv}/bin/${name} $out/bin/${name} \
--suffix PATH : "${runtimePath}" \
--set HERMES_BUNDLED_SKILLS $out/share/hermes-agent/skills \
--set HERMES_BUNDLED_PLUGINS $out/share/hermes-agent/plugins \
--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 ${nodejs_22}/bin/node \
${lib.optionalString (rev != null) ''--set HERMES_REVISION ${rev} \''}
${lib.optionalString (extraPythonPackages != [ ]) ''--suffix PYTHONPATH : "${pythonPath}"''}
'')
[
"hermes"
"hermes-agent"
"hermes-acp"
]
}
${lib.optionalString (extraPythonPackages != [ ]) ''
echo "=== Checking for plugin/core package collisions ==="
${hermesVenv}/bin/python3 -c "
import pathlib, sys, re import pathlib, sys, re
def canonical(name): def canonical(name):
@@ -162,7 +121,50 @@ for edir in extras_dirs:
break break
print('No collisions found.') print('No collisions found.')
" '';
in
stdenv.mkDerivation {
pname = "hermes-agent";
version = (fromTOML (builtins.readFile ../pyproject.toml)).project.version;
dontUnpack = true;
dontBuild = true;
nativeBuildInputs = [ makeWrapper ];
installPhase = ''
runHook preInstall
mkdir -p $out/share/hermes-agent $out/bin
cp -r ${bundledSkills} $out/share/hermes-agent/skills
cp -r ${bundledPlugins} $out/share/hermes-agent/plugins
cp -r ${hermesWeb} $out/share/hermes-agent/web_dist
mkdir -p $out/ui-tui
cp -r ${hermesTui}/lib/hermes-tui/* $out/ui-tui/
${lib.concatMapStringsSep "\n"
(name: ''
makeWrapper ${hermesVenv}/bin/${name} $out/bin/${name} \
--suffix PATH : "${runtimePath}" \
--set HERMES_BUNDLED_SKILLS $out/share/hermes-agent/skills \
--set HERMES_BUNDLED_PLUGINS $out/share/hermes-agent/plugins \
--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} \
${lib.optionalString (rev != null) ''--set HERMES_REVISION ${rev} \''}
${lib.optionalString (extraPythonPackages != [ ]) ''--suffix PYTHONPATH : "${pythonPath}"''}
'')
[
"hermes"
"hermes-agent"
"hermes-acp"
]
}
${lib.optionalString (extraPythonPackages != [ ]) ''
echo "=== Checking for plugin/core package collisions ==="
${hermesVenv}/bin/python3 -c "${checkPackageCollisions}"
echo "=== No collisions ===" echo "=== No collisions ==="
''} ''}
@@ -170,7 +172,12 @@ print('No collisions found.')
''; '';
passthru = { passthru = {
inherit hermesTui hermesWeb hermesNpmLib hermesVenv; inherit
hermesTui
hermesWeb
hermesNpmLib
hermesVenv
;
devShellHook = '' devShellHook = ''
STAMP=".nix-stamps/hermes-agent" STAMP=".nix-stamps/hermes-agent"

View File

@@ -1,11 +1,16 @@
# nix/lib.nix — Shared helpers for nix stuff # nix/lib.nix — Shared helpers for nix stuff
{ pkgs, npm-lockfile-fix }: {
pkgs,
npm-lockfile-fix,
nodejs,
}:
{ {
# Returns a buildNpmPackage-compatible attrs set that provides: # Returns a buildNpmPackage-compatible attrs set that provides:
# patchPhase — ensures lockfile has exactly one trailing newline # patchPhase — ensures lockfile has exactly one trailing newline
# nativeBuildInputs — [ updateLockfileScript ] (list, prepend with ++ for more) # nativeBuildInputs — [ updateLockfileScript ] (list, prepend with ++ for more)
# passthru.devShellHook — stamp-checked npm install + hash auto-update # passthru.devShellHook — stamp-checked npm install + hash auto-update
# passthru.npmLockfile — metadata for mkFixLockfiles # passthru.npmLockfile — metadata for mkFixLockfiles
# nodejs — fixed nodejs version for all packages we use in the repo
# #
# NOTE: npmConfigHook runs `diff` between the source lockfile and the # NOTE: npmConfigHook runs `diff` between the source lockfile and the
# npm-deps cache lockfile. fetchNpmDeps preserves whatever trailing # npm-deps cache lockfile. fetchNpmDeps preserves whatever trailing
@@ -24,6 +29,7 @@
nixFile ? "nix/${attr}.nix", # defaults to nix/<attr>.nix nixFile ? "nix/${attr}.nix", # defaults to nix/<attr>.nix
}: }:
{ {
inherit nodejs;
patchPhase = '' patchPhase = ''
runHook prePatch runHook prePatch
# Normalize trailing newlines so source and npm-deps always match, # Normalize trailing newlines so source and npm-deps always match,
@@ -56,8 +62,8 @@
cd "$REPO_ROOT/${folder}" cd "$REPO_ROOT/${folder}"
rm -rf node_modules/ rm -rf node_modules/
npm cache clean --force ${pkgs.lib.getExe' nodejs "npm"} cache clean --force
CI=true npm install CI=true ${pkgs.lib.getExe' nodejs "npm"} install
${pkgs.lib.getExe npm-lockfile-fix} ./package-lock.json ${pkgs.lib.getExe npm-lockfile-fix} ./package-lock.json
NIX_FILE="$REPO_ROOT/${nixFile}" NIX_FILE="$REPO_ROOT/${nixFile}"
@@ -83,7 +89,7 @@
STAMP_VALUE="$(_hermes_npm_stamp)" STAMP_VALUE="$(_hermes_npm_stamp)"
if [ ! -f "$STAMP" ] || [ "$(cat "$STAMP")" != "$STAMP_VALUE" ]; then if [ ! -f "$STAMP" ] || [ "$(cat "$STAMP")" != "$STAMP_VALUE" ]; then
echo "${pname}: installing npm dependencies..." echo "${pname}: installing npm dependencies..."
( cd ${folder} && CI=true npm install --silent --no-fund --no-audit 2>/dev/null ) ( cd ${folder} && CI=true ${pkgs.lib.getExe' nodejs "npm"} install --silent --no-fund --no-audit 2>/dev/null )
# Auto-update the nix hash so it stays in sync with the lockfile # Auto-update the nix hash so it stays in sync with the lockfile
echo "${pname}: prefetching npm deps..." echo "${pname}: prefetching npm deps..."
@@ -92,7 +98,7 @@
sed -i "s|hash = \"sha256-[A-Za-z0-9+/=]+\"|hash = \"$NEW_HASH\";|" "$NIX_FILE" sed -i "s|hash = \"sha256-[A-Za-z0-9+/=]+\"|hash = \"$NEW_HASH\";|" "$NIX_FILE"
echo "${pname}: updated hash to $NEW_HASH" echo "${pname}: updated hash to $NEW_HASH"
else else
echo "${pname}: warning: prefetch failed, run 'nix run .#fix-lockfiles -- --apply' manually" >&2 echo "${pname}: warning: prefetch failed, run 'nix run .#fix-lockfiles' manually" >&2
fi fi
mkdir -p .nix-stamps mkdir -p .nix-stamps
@@ -112,6 +118,7 @@
# Invocations: # Invocations:
# fix-lockfiles --check # exit 1 if any hash is stale # fix-lockfiles --check # exit 1 if any hash is stale
# fix-lockfiles --apply # rewrite stale hashes in place # fix-lockfiles --apply # rewrite stale hashes in place
# fix-lockfiles # alias of --apply
# Writes machine-readable fields (stale, changed, report) to $GITHUB_OUTPUT # Writes machine-readable fields (stale, changed, report) to $GITHUB_OUTPUT
# when set, so CI workflows can post a sticky PR comment directly. # when set, so CI workflows can post a sticky PR comment directly.
mkFixLockfiles = mkFixLockfiles =
@@ -124,7 +131,7 @@
in in
pkgs.writeShellScriptBin "fix-lockfiles" '' pkgs.writeShellScriptBin "fix-lockfiles" ''
set -uox pipefail set -uox pipefail
MODE="''${1:---check}" MODE="''${1:---apply}"
case "$MODE" in case "$MODE" in
--check|--apply) ;; --check|--apply) ;;
-h|--help) -h|--help)
@@ -222,7 +229,7 @@
if [ "$STALE" -eq 1 ] && [ "$MODE" = "--check" ]; then if [ "$STALE" -eq 1 ] && [ "$MODE" = "--check" ]; then
echo echo
echo "Stale lockfile hashes detected. Run:" echo "Stale lockfile hashes detected. Run:"
echo " nix run .#fix-lockfiles -- --apply" echo " nix run .#fix-lockfiles"
exit 1 exit 1
fi fi

View File

@@ -4,7 +4,7 @@ let
src = ../ui-tui; src = ../ui-tui;
npmDeps = pkgs.fetchNpmDeps { npmDeps = pkgs.fetchNpmDeps {
inherit src; inherit src;
hash = "sha256-a/HGI9OgVcTnZrMXA7xFMGnFoVxyHe95fulVz+WNYB0="; hash = "sha256-OyntL0iahyp247guDL0W6Vfp0e4OPJT3PJ1aqzF3Stg=";
}; };
npm = hermesNpmLib.mkNpmPassthru { folder = "ui-tui"; attr = "tui"; pname = "hermes-tui"; }; npm = hermesNpmLib.mkNpmPassthru { folder = "ui-tui"; attr = "tui"; pname = "hermes-tui"; };

View File

@@ -8,11 +8,13 @@ let
}; };
npm = hermesNpmLib.mkNpmPassthru { folder = "web"; attr = "web"; pname = "hermes-web"; }; npm = hermesNpmLib.mkNpmPassthru { folder = "web"; attr = "web"; pname = "hermes-web"; };
packageJson = builtins.fromJSON (builtins.readFile (src + "/package.json"));
version = packageJson.version;
in in
pkgs.buildNpmPackage (npm // { pkgs.buildNpmPackage (npm // {
pname = "hermes-web"; pname = "hermes-web";
version = "0.0.0"; inherit src npmDeps version;
inherit src npmDeps;
doCheck = false; doCheck = false;

View File

@@ -13,6 +13,7 @@
"ink": "^6.8.0", "ink": "^6.8.0",
"ink-text-input": "^6.0.0", "ink-text-input": "^6.0.0",
"react": "^19.2.4", "react": "^19.2.4",
"three.js": "^0.77.1",
"unicode-animations": "^1.0.3" "unicode-animations": "^1.0.3"
}, },
"devDependencies": { "devDependencies": {
@@ -124,7 +125,6 @@
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.29.0", "@babel/code-frame": "^7.29.0",
"@babel/generator": "^7.29.0", "@babel/generator": "^7.29.0",
@@ -502,6 +502,31 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@emnapi/core": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@emnapi/wasi-threads": "1.2.1",
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/runtime": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/wasi-threads": { "node_modules/@emnapi/wasi-threads": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
@@ -1676,7 +1701,6 @@
"integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"undici-types": "~7.19.0" "undici-types": "~7.19.0"
} }
@@ -1687,7 +1711,6 @@
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"csstype": "^3.2.2" "csstype": "^3.2.2"
} }
@@ -1698,7 +1721,6 @@
"integrity": "sha512-eSkwoemjo76bdXl2MYqtxg51HNwUSkWfODUOQ3PaTLZGh9uIWWFZIjyjaJnex7wXDu+TRx+ATsnSxdN9YWfRTQ==", "integrity": "sha512-eSkwoemjo76bdXl2MYqtxg51HNwUSkWfODUOQ3PaTLZGh9uIWWFZIjyjaJnex7wXDu+TRx+ATsnSxdN9YWfRTQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@eslint-community/regexpp": "^4.12.2", "@eslint-community/regexpp": "^4.12.2",
"@typescript-eslint/scope-manager": "8.58.1", "@typescript-eslint/scope-manager": "8.58.1",
@@ -1728,7 +1750,6 @@
"integrity": "sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw==", "integrity": "sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "8.58.1", "@typescript-eslint/scope-manager": "8.58.1",
"@typescript-eslint/types": "8.58.1", "@typescript-eslint/types": "8.58.1",
@@ -2046,7 +2067,6 @@
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"bin": { "bin": {
"acorn": "bin/acorn" "acorn": "bin/acorn"
}, },
@@ -2449,7 +2469,6 @@
} }
], ],
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"baseline-browser-mapping": "^2.10.12", "baseline-browser-mapping": "^2.10.12",
"caniuse-lite": "^1.0.30001782", "caniuse-lite": "^1.0.30001782",
@@ -3185,7 +3204,6 @@
"integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1", "@eslint-community/regexpp": "^4.12.1",
@@ -3317,7 +3335,6 @@
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"funding": { "funding": {
"url": "https://github.com/sponsors/colinhacks" "url": "https://github.com/sponsors/colinhacks"
} }
@@ -4226,7 +4243,6 @@
"resolved": "https://registry.npmjs.org/ink-text-input/-/ink-text-input-6.0.0.tgz", "resolved": "https://registry.npmjs.org/ink-text-input/-/ink-text-input-6.0.0.tgz",
"integrity": "sha512-Fw64n7Yha5deb1rHY137zHTAbSTNelUKuB5Kkk2HACXEtwIHBCf9OH2tP/LQ9fRYTl1F0dZgbW0zPnZk6FA9Lw==", "integrity": "sha512-Fw64n7Yha5deb1rHY137zHTAbSTNelUKuB5Kkk2HACXEtwIHBCf9OH2tP/LQ9fRYTl1F0dZgbW0zPnZk6FA9Lw==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"chalk": "^5.3.0", "chalk": "^5.3.0",
"type-fest": "^4.18.2" "type-fest": "^4.18.2"
@@ -5663,7 +5679,6 @@
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=12" "node": ">=12"
}, },
@@ -5773,7 +5788,6 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz", "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz",
"integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==", "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==",
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@@ -6513,6 +6527,23 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/three": {
"version": "0.77.0",
"resolved": "https://registry.npmjs.org/three/-/three-0.77.0.tgz",
"integrity": "sha512-YWEp8ahs2l+6fAFVbanLVQoSBwVq5jDct3nZdBSHHXb5I/w5oy/LCMAzIOAguKWclRqcjR4W1BeP5QBnftGbpA==",
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/three.js": {
"version": "0.77.1",
"resolved": "https://registry.npmjs.org/three.js/-/three.js-0.77.1.tgz",
"integrity": "sha512-lVMYlBXhhHlZtsF+cQdev6WCm2fSWs3I+A6Z63j6TBmkVXOYgdo9AUCRemfsw5mllqWx23VubJ5Qt8/uWKQpJA==",
"dependencies": {
"three": "0.77.0"
}
},
"node_modules/tinybench": { "node_modules/tinybench": {
"version": "2.9.0", "version": "2.9.0",
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
@@ -6598,7 +6629,6 @@
"integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"esbuild": "~0.27.0", "esbuild": "~0.27.0",
"get-tsconfig": "^4.7.5" "get-tsconfig": "^4.7.5"
@@ -6725,7 +6755,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"
@@ -6835,7 +6864,6 @@
"integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==", "integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"lightningcss": "^1.32.0", "lightningcss": "^1.32.0",
"picomatch": "^4.0.4", "picomatch": "^4.0.4",
@@ -7251,7 +7279,6 @@
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"funding": { "funding": {
"url": "https://github.com/sponsors/colinhacks" "url": "https://github.com/sponsors/colinhacks"
} }

View File

@@ -22,6 +22,7 @@
"ink": "^6.8.0", "ink": "^6.8.0",
"ink-text-input": "^6.0.0", "ink-text-input": "^6.0.0",
"react": "^19.2.4", "react": "^19.2.4",
"three.js": "^0.77.1",
"unicode-animations": "^1.0.3" "unicode-animations": "^1.0.3"
}, },
"devDependencies": { "devDependencies": {