mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-01 08:21:50 +08:00
Compare commits
6 Commits
opencode-p
...
dont-merge
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
847cf0335a | ||
|
|
3ac5a6b474 | ||
|
|
d79cbb7763 | ||
|
|
cdda9847cd | ||
|
|
978c0aed85 | ||
|
|
f4745a2c72 |
76
.github/workflows/nix-lockfile-check.yml
vendored
76
.github/workflows/nix-lockfile-check.yml
vendored
@@ -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
|
||||
4
.github/workflows/nix-lockfile-fix.yml
vendored
4
.github/workflows/nix-lockfile-fix.yml
vendored
@@ -28,7 +28,7 @@ concurrency:
|
||||
jobs:
|
||||
# ── Auto-fix on main ───────────────────────────────────────────────
|
||||
# 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.
|
||||
#
|
||||
# Safety invariants:
|
||||
@@ -207,7 +207,7 @@ jobs:
|
||||
|
||||
- name: Apply lockfile hashes
|
||||
id: apply
|
||||
run: nix run .#fix-lockfiles -- --apply
|
||||
run: nix run .#fix-lockfiles
|
||||
|
||||
- name: Commit & push
|
||||
if: steps.apply.outputs.changed == 'true'
|
||||
|
||||
82
.github/workflows/nix.yml
vendored
82
.github/workflows/nix.yml
vendored
@@ -7,6 +7,7 @@ on:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: nix-${{ github.ref }}
|
||||
@@ -24,12 +25,93 @@ jobs:
|
||||
- uses: ./.github/actions/nix-setup
|
||||
with:
|
||||
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
|
||||
id: flake
|
||||
if: runner.os == 'Linux'
|
||||
continue-on-error: true
|
||||
run: nix flake check --print-build-logs
|
||||
|
||||
- name: Build package
|
||||
id: build
|
||||
if: runner.os == 'Linux'
|
||||
continue-on-error: true
|
||||
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)
|
||||
if: runner.os == 'macOS'
|
||||
run: nix flake show --json > /dev/null
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
# transitive deps like onnxruntime that lack compatible wheels on
|
||||
# aarch64-darwin. The package and devShell still work on macOS.
|
||||
{ inputs, ... }: {
|
||||
perSystem = { pkgs, system, lib, ... }:
|
||||
perSystem = { pkgs, lib, self', ... }:
|
||||
let
|
||||
hermes-agent = inputs.self.packages.${system}.default;
|
||||
hermes-agent = self'.packages.default;
|
||||
hermesVenv = hermes-agent.hermesVenv;
|
||||
|
||||
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;
|
||||
in pkgs.runCommand "hermes-cross-eval" { } (
|
||||
if failures != [] then
|
||||
builtins.throw "Package fails to evaluate on:\n${failMsg}"
|
||||
throw "Package fails to evaluate on:\n${failMsg}"
|
||||
else ''
|
||||
echo "PASS: package evaluates on all ${toString (builtins.length targetSystems)} platforms"
|
||||
mkdir -p $out
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
# 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.
|
||||
{ inputs, ... }: {
|
||||
perSystem = { pkgs, system, ... }:
|
||||
{ ... }:
|
||||
{
|
||||
perSystem =
|
||||
{ pkgs, self', ... }:
|
||||
let
|
||||
hermes-agent = inputs.self.packages.${system}.default;
|
||||
hermes-tui = inputs.self.packages.${system}.tui;
|
||||
hermes-web = inputs.self.packages.${system}.web;
|
||||
packages = [ hermes-agent hermes-tui hermes-web ];
|
||||
in {
|
||||
packages = builtins.attrValues self'.packages;
|
||||
in
|
||||
{
|
||||
devShells.default = pkgs.mkShell {
|
||||
inputsFrom = packages;
|
||||
packages = with pkgs; [
|
||||
python312 uv nodejs_22 ripgrep git openssh ffmpeg
|
||||
uv
|
||||
];
|
||||
|
||||
shellHook = let
|
||||
hooks = map (p: p.passthru.devShellHook or "") packages;
|
||||
combined = pkgs.lib.concatStringsSep "\n" (builtins.filter (h: h != "") hooks);
|
||||
in ''
|
||||
echo "Hermes Agent dev shell"
|
||||
${combined}
|
||||
echo "Ready. Run 'hermes' to start."
|
||||
'';
|
||||
shellHook =
|
||||
let
|
||||
hooks = map (p: p.passthru.devShellHook or "") packages;
|
||||
combined = pkgs.lib.concatStringsSep "\n" (builtins.filter (h: h != "") hooks);
|
||||
in
|
||||
''
|
||||
echo "Hermes Agent dev shell"
|
||||
${combined}
|
||||
echo "Ready. Run 'hermes' to start."
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -27,12 +27,13 @@
|
||||
extraPythonPackages ? [ ],
|
||||
}:
|
||||
let
|
||||
nodejs = nodejs_22;
|
||||
hermesVenv = callPackage ./python.nix {
|
||||
inherit uv2nix pyproject-nix pyproject-build-systems;
|
||||
};
|
||||
|
||||
hermesNpmLib = callPackage ./lib.nix {
|
||||
inherit npm-lockfile-fix;
|
||||
inherit npm-lockfile-fix nodejs;
|
||||
};
|
||||
|
||||
hermesTui = callPackage ./tui.nix {
|
||||
@@ -57,7 +58,7 @@ let
|
||||
};
|
||||
|
||||
runtimeDeps = [
|
||||
nodejs_22
|
||||
nodejs
|
||||
ripgrep
|
||||
git
|
||||
openssh
|
||||
@@ -82,10 +83,49 @@ let
|
||||
builtins.hashString "sha256" (builtins.readFile ../uv.lock)
|
||||
else
|
||||
"none";
|
||||
checkPackageCollisions = ''
|
||||
import pathlib, sys, re
|
||||
|
||||
def canonical(name):
|
||||
return re.sub(r'[-_.]+', '-', name).lower()
|
||||
|
||||
# Collect core venv package names
|
||||
core = set()
|
||||
venv_sp = pathlib.Path('${hermesVenv}/${sitePackagesPath}')
|
||||
for di in venv_sp.glob('*.dist-info'):
|
||||
meta = di / 'METADATA'
|
||||
if meta.exists():
|
||||
for line in meta.read_text().splitlines():
|
||||
if line.startswith('Name:'):
|
||||
core.add(canonical(line.split(':', 1)[1].strip()))
|
||||
break
|
||||
|
||||
# Check each extra package for collisions
|
||||
extras_dirs = [${lib.concatMapStringsSep ", " (p: "'${toString p}'") allExtraPythonPackages}]
|
||||
for edir in extras_dirs:
|
||||
sp = pathlib.Path(edir) / '${sitePackagesPath}'
|
||||
if not sp.exists():
|
||||
continue
|
||||
for di in sp.glob('*.dist-info'):
|
||||
meta = di / 'METADATA'
|
||||
if not meta.exists():
|
||||
continue
|
||||
for line in meta.read_text().splitlines():
|
||||
if line.startswith('Name:'):
|
||||
pkg = canonical(line.split(':', 1)[1].strip())
|
||||
if pkg in core:
|
||||
print(f'ERROR: plugin package \"{pkg}\" collides with a package in hermes sealed venv', file=sys.stderr)
|
||||
print(f' from: {di}', file=sys.stderr)
|
||||
print(f' Remove this dependency from extraPythonPackages.', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
break
|
||||
|
||||
print('No collisions found.')
|
||||
'';
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
pname = "hermes-agent";
|
||||
version = (builtins.fromTOML (builtins.readFile ../pyproject.toml)).project.version;
|
||||
version = (fromTOML (builtins.readFile ../pyproject.toml)).project.version;
|
||||
|
||||
dontUnpack = true;
|
||||
dontBuild = true;
|
||||
@@ -111,7 +151,7 @@ stdenv.mkDerivation {
|
||||
--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 \
|
||||
--set HERMES_NODE ${lib.getExe nodejs} \
|
||||
${lib.optionalString (rev != null) ''--set HERMES_REVISION ${rev} \''}
|
||||
${lib.optionalString (extraPythonPackages != [ ]) ''--suffix PYTHONPATH : "${pythonPath}"''}
|
||||
'')
|
||||
@@ -124,53 +164,20 @@ stdenv.mkDerivation {
|
||||
|
||||
${lib.optionalString (extraPythonPackages != [ ]) ''
|
||||
echo "=== Checking for plugin/core package collisions ==="
|
||||
${hermesVenv}/bin/python3 -c "
|
||||
import pathlib, sys, re
|
||||
|
||||
def canonical(name):
|
||||
return re.sub(r'[-_.]+', '-', name).lower()
|
||||
|
||||
# Collect core venv package names
|
||||
core = set()
|
||||
venv_sp = pathlib.Path('${hermesVenv}/${sitePackagesPath}')
|
||||
for di in venv_sp.glob('*.dist-info'):
|
||||
meta = di / 'METADATA'
|
||||
if meta.exists():
|
||||
for line in meta.read_text().splitlines():
|
||||
if line.startswith('Name:'):
|
||||
core.add(canonical(line.split(':', 1)[1].strip()))
|
||||
break
|
||||
|
||||
# Check each extra package for collisions
|
||||
extras_dirs = [${lib.concatMapStringsSep ", " (p: "'${toString p}'") allExtraPythonPackages}]
|
||||
for edir in extras_dirs:
|
||||
sp = pathlib.Path(edir) / '${sitePackagesPath}'
|
||||
if not sp.exists():
|
||||
continue
|
||||
for di in sp.glob('*.dist-info'):
|
||||
meta = di / 'METADATA'
|
||||
if not meta.exists():
|
||||
continue
|
||||
for line in meta.read_text().splitlines():
|
||||
if line.startswith('Name:'):
|
||||
pkg = canonical(line.split(':', 1)[1].strip())
|
||||
if pkg in core:
|
||||
print(f'ERROR: plugin package \"{pkg}\" collides with a package in hermes sealed venv', file=sys.stderr)
|
||||
print(f' from: {di}', file=sys.stderr)
|
||||
print(f' Remove this dependency from extraPythonPackages.', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
break
|
||||
|
||||
print('No collisions found.')
|
||||
"
|
||||
echo "=== No collisions ==="
|
||||
${hermesVenv}/bin/python3 -c "${checkPackageCollisions}"
|
||||
echo "=== No collisions ==="
|
||||
''}
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
inherit hermesTui hermesWeb hermesNpmLib hermesVenv;
|
||||
inherit
|
||||
hermesTui
|
||||
hermesWeb
|
||||
hermesNpmLib
|
||||
hermesVenv
|
||||
;
|
||||
|
||||
devShellHook = ''
|
||||
STAMP=".nix-stamps/hermes-agent"
|
||||
|
||||
25
nix/lib.nix
25
nix/lib.nix
@@ -1,11 +1,16 @@
|
||||
# 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:
|
||||
# patchPhase — ensures lockfile has exactly one trailing newline
|
||||
# nativeBuildInputs — [ updateLockfileScript ] (list, prepend with ++ for more)
|
||||
# patchPhase — ensures lockfile has exactly one trailing newline
|
||||
# nativeBuildInputs — [ updateLockfileScript ] (list, prepend with ++ for more)
|
||||
# passthru.devShellHook — stamp-checked npm install + hash auto-update
|
||||
# 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
|
||||
# npm-deps cache lockfile. fetchNpmDeps preserves whatever trailing
|
||||
@@ -24,6 +29,7 @@
|
||||
nixFile ? "nix/${attr}.nix", # defaults to nix/<attr>.nix
|
||||
}:
|
||||
{
|
||||
inherit nodejs;
|
||||
patchPhase = ''
|
||||
runHook prePatch
|
||||
# Normalize trailing newlines so source and npm-deps always match,
|
||||
@@ -56,8 +62,8 @@
|
||||
|
||||
cd "$REPO_ROOT/${folder}"
|
||||
rm -rf node_modules/
|
||||
npm cache clean --force
|
||||
CI=true npm install
|
||||
${pkgs.lib.getExe' nodejs "npm"} cache clean --force
|
||||
CI=true ${pkgs.lib.getExe' nodejs "npm"} install
|
||||
${pkgs.lib.getExe npm-lockfile-fix} ./package-lock.json
|
||||
|
||||
NIX_FILE="$REPO_ROOT/${nixFile}"
|
||||
@@ -83,7 +89,7 @@
|
||||
STAMP_VALUE="$(_hermes_npm_stamp)"
|
||||
if [ ! -f "$STAMP" ] || [ "$(cat "$STAMP")" != "$STAMP_VALUE" ]; then
|
||||
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
|
||||
echo "${pname}: prefetching npm deps..."
|
||||
@@ -92,7 +98,7 @@
|
||||
sed -i "s|hash = \"sha256-[A-Za-z0-9+/=]+\"|hash = \"$NEW_HASH\";|" "$NIX_FILE"
|
||||
echo "${pname}: updated hash to $NEW_HASH"
|
||||
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
|
||||
|
||||
mkdir -p .nix-stamps
|
||||
@@ -112,6 +118,7 @@
|
||||
# Invocations:
|
||||
# fix-lockfiles --check # exit 1 if any hash is stale
|
||||
# fix-lockfiles --apply # rewrite stale hashes in place
|
||||
# fix-lockfiles # alias of --apply
|
||||
# Writes machine-readable fields (stale, changed, report) to $GITHUB_OUTPUT
|
||||
# when set, so CI workflows can post a sticky PR comment directly.
|
||||
mkFixLockfiles =
|
||||
@@ -124,7 +131,7 @@
|
||||
in
|
||||
pkgs.writeShellScriptBin "fix-lockfiles" ''
|
||||
set -uox pipefail
|
||||
MODE="''${1:---check}"
|
||||
MODE="''${1:---apply}"
|
||||
case "$MODE" in
|
||||
--check|--apply) ;;
|
||||
-h|--help)
|
||||
@@ -222,7 +229,7 @@
|
||||
if [ "$STALE" -eq 1 ] && [ "$MODE" = "--check" ]; then
|
||||
echo
|
||||
echo "Stale lockfile hashes detected. Run:"
|
||||
echo " nix run .#fix-lockfiles -- --apply"
|
||||
echo " nix run .#fix-lockfiles"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ let
|
||||
src = ../ui-tui;
|
||||
npmDeps = pkgs.fetchNpmDeps {
|
||||
inherit src;
|
||||
hash = "sha256-a/HGI9OgVcTnZrMXA7xFMGnFoVxyHe95fulVz+WNYB0=";
|
||||
hash = "sha256-OyntL0iahyp247guDL0W6Vfp0e4OPJT3PJ1aqzF3Stg=";
|
||||
};
|
||||
|
||||
npm = hermesNpmLib.mkNpmPassthru { folder = "ui-tui"; attr = "tui"; pname = "hermes-tui"; };
|
||||
|
||||
@@ -8,11 +8,13 @@ let
|
||||
};
|
||||
|
||||
npm = hermesNpmLib.mkNpmPassthru { folder = "web"; attr = "web"; pname = "hermes-web"; };
|
||||
|
||||
packageJson = builtins.fromJSON (builtins.readFile (src + "/package.json"));
|
||||
version = packageJson.version;
|
||||
in
|
||||
pkgs.buildNpmPackage (npm // {
|
||||
pname = "hermes-web";
|
||||
version = "0.0.0";
|
||||
inherit src npmDeps;
|
||||
inherit src npmDeps version;
|
||||
|
||||
doCheck = false;
|
||||
|
||||
|
||||
59
ui-tui/package-lock.json
generated
59
ui-tui/package-lock.json
generated
@@ -13,6 +13,7 @@
|
||||
"ink": "^6.8.0",
|
||||
"ink-text-input": "^6.0.0",
|
||||
"react": "^19.2.4",
|
||||
"three.js": "^0.77.1",
|
||||
"unicode-animations": "^1.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -124,7 +125,6 @@
|
||||
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.29.0",
|
||||
"@babel/generator": "^7.29.0",
|
||||
@@ -502,6 +502,31 @@
|
||||
"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": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
|
||||
@@ -1676,7 +1701,6 @@
|
||||
"integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~7.19.0"
|
||||
}
|
||||
@@ -1687,7 +1711,6 @@
|
||||
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"csstype": "^3.2.2"
|
||||
}
|
||||
@@ -1698,7 +1721,6 @@
|
||||
"integrity": "sha512-eSkwoemjo76bdXl2MYqtxg51HNwUSkWfODUOQ3PaTLZGh9uIWWFZIjyjaJnex7wXDu+TRx+ATsnSxdN9YWfRTQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.12.2",
|
||||
"@typescript-eslint/scope-manager": "8.58.1",
|
||||
@@ -1728,7 +1750,6 @@
|
||||
"integrity": "sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.58.1",
|
||||
"@typescript-eslint/types": "8.58.1",
|
||||
@@ -2046,7 +2067,6 @@
|
||||
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@@ -2449,7 +2469,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.10.12",
|
||||
"caniuse-lite": "^1.0.30001782",
|
||||
@@ -3185,7 +3204,6 @@
|
||||
"integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.8.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
@@ -3317,7 +3335,6 @@
|
||||
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"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",
|
||||
"integrity": "sha512-Fw64n7Yha5deb1rHY137zHTAbSTNelUKuB5Kkk2HACXEtwIHBCf9OH2tP/LQ9fRYTl1F0dZgbW0zPnZk6FA9Lw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"chalk": "^5.3.0",
|
||||
"type-fest": "^4.18.2"
|
||||
@@ -5663,7 +5679,6 @@
|
||||
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -5773,7 +5788,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz",
|
||||
"integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -6513,6 +6527,23 @@
|
||||
"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": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
|
||||
@@ -6598,7 +6629,6 @@
|
||||
"integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "~0.27.0",
|
||||
"get-tsconfig": "^4.7.5"
|
||||
@@ -6725,7 +6755,6 @@
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -6835,7 +6864,6 @@
|
||||
"integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"lightningcss": "^1.32.0",
|
||||
"picomatch": "^4.0.4",
|
||||
@@ -7251,7 +7279,6 @@
|
||||
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"ink": "^6.8.0",
|
||||
"ink-text-input": "^6.0.0",
|
||||
"react": "^19.2.4",
|
||||
"three.js": "^0.77.1",
|
||||
"unicode-animations": "^1.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
Reference in New Issue
Block a user