-
Notifications
You must be signed in to change notification settings - Fork 32
feat: add nix flake (for nix & nixos users) with package, overlay, and home-manager module #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
df95efc
17eb9eb
b4a24ad
db92153
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,28 @@ | ||||||||||
| name: Node.js CI | ||||||||||
|
|
||||||||||
| on: | ||||||||||
| workflow_dispatch: | ||||||||||
| push: | ||||||||||
| branches: [ main feat/multi-account ] | ||||||||||
| pull_request: | ||||||||||
| branches: [ main feat/multi-account ] | ||||||||||
|
|
||||||||||
| jobs: | ||||||||||
| build: | ||||||||||
| runs-on: ubuntu-latest | ||||||||||
|
Comment on lines
+11
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🛡️ Analyzed with Security Review | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: sed -n '1,40p' .github/workflows/ci.ymlRepository: linuxhsj/WebModel Length of output: 717 Security Misconfiguration Reachability: External Declare least-privilege workflow permissions. This workflow runs repository-controlled npm scripts and does not define 🧰 Tools🪛 zizmor (1.29.0)[warning] 11-29: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block (excessive-permissions) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||
|
|
||||||||||
| strategy: | ||||||||||
| matrix: | ||||||||||
| node-version: [20.x, 22.x] | ||||||||||
|
|
||||||||||
| steps: | ||||||||||
| - uses: actions/checkout@v4 | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🛡️ Analyzed with Security Review | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- .github/workflows/ci.yml ---'
cat -n .github/workflows/ci.yml
printf '%s\n' '--- package.json scripts ---'
sed -n '1,35p' package.jsonRepository: linuxhsj/WebModel Length of output: 1789 🌐 Web query:
💡 Result: In Citations:
Sensitive Data Exposure Reachability: External Disable checkout credential persistence.
Set Proposed fix- - uses: actions/checkout@v4
+ - uses: actions/checkout@v4
+ with:
+ persist-credentials: false📝 Committable suggestion
Suggested change
🧰 Tools🪛 zizmor (1.29.0)[warning] 19-19: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false (artipacked) [warning] 11-29: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block (excessive-permissions) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||
| - name: Use Node.js ${{ matrix.node-version }} | ||||||||||
| uses: actions/setup-node@v4 | ||||||||||
| with: | ||||||||||
| node-version: ${{ matrix.node-version }} | ||||||||||
| cache: 'npm' | ||||||||||
| - run: npm ci | ||||||||||
| - run: npm run typecheck | ||||||||||
| - run: npm run build | ||||||||||
| - run: npm test | ||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,3 +6,4 @@ dist/ | |
| coverage/ | ||
| *.log | ||
| .DS_Store | ||
| .result | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,182 @@ | ||
| { | ||
| description = "web-model-bridge — bridge web AI models through an OpenAI-compatible API"; | ||
|
|
||
| inputs = { | ||
| nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; | ||
| flake-utils.url = "github:numtide/flake-utils"; | ||
| home-manager = { | ||
| url = "github:nix-community/home-manager"; | ||
| inputs.nixpkgs.follows = "nixpkgs"; | ||
| }; | ||
| }; | ||
|
|
||
| outputs = { | ||
| self, | ||
| nixpkgs, | ||
| flake-utils, | ||
| home-manager, | ||
| }: let | ||
| # ── package definition ──────────────────────────────────────────────── | ||
| # Accepts the pkgs set so we can reuse it from any nixpkgs instance. | ||
| mkWebModelBridge = pkgs: | ||
| pkgs.buildNpmPackage { | ||
| pname = "web-model-bridge"; | ||
| version = "0.1.0"; | ||
|
|
||
| src = ./.; | ||
|
|
||
| # Run `nix build` once with a fake hash, let nix tell you the real one, | ||
| # then replace the placeholder below. | ||
| npmDepsHash = "sha256-wHoZ9lUMtXQ8LhSCQCc30d9K7+ByfrF6/BS3B1PVvt0="; | ||
|
|
||
| # tsup produces a single ESM bundle; makeWrapper creates the bin wrapper. | ||
| nativeBuildInputs = [pkgs.nodejs_22 pkgs.makeWrapper]; | ||
|
|
||
| # The npm "build" script runs tsup. | ||
| # buildNpmPackage runs `npm run build` by default when a build script exists. | ||
|
|
||
| # Copy the dashboard static files that tsup's onSuccess hook normally handles. | ||
| postBuild = '' | ||
| mkdir -p dist/dashboard | ||
| for f in src/dashboard/index.html src/dashboard/app.js src/dashboard/style.css; do | ||
| [ -f "$f" ] && cp "$f" dist/dashboard/ || true | ||
| done | ||
| ''; | ||
|
|
||
| installPhase = '' | ||
| runHook preInstall | ||
|
|
||
| mkdir -p $out/lib/web-model-bridge | ||
| cp -r dist $out/lib/web-model-bridge/ | ||
|
|
||
| # Keep node_modules for runtime requires (playwright-core etc.) | ||
| cp -r node_modules $out/lib/web-model-bridge/ | ||
|
|
||
| mkdir -p $out/bin | ||
| makeWrapper ${pkgs.nodejs_22}/bin/node $out/bin/web-model-bridge \ | ||
| --add-flags "$out/lib/web-model-bridge/dist/cli.js" | ||
|
Comment on lines
+49
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Confirm that the project declares ESM and that the install phase omits it.
jq -r '.type // "<no type field>"' package.json
sed -n '41,54p' flake.nixRepository: linuxhsj/WebModel Length of output: 643 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "package.json type/importer fields:"
jq '{type, imports}' package.json
echo
echo "dist/cli.js first lines:"
if [ -f dist/cli.js ]; then
sed -n '1,4p' dist/cli.js
else
echo "dist/cli.js not present"
fi
echo
echo "Source files referencing Node package type / ESM setup:"
rg -n '"type"\s*:|"main"|import\s*[{]|export\s+' src flake.nix package.json 2>/dev/null | head -80Repository: linuxhsj/WebModel Length of output: 6337 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "Package manager lock files:"
git ls-files | rg '^(package-lock\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb?|npm-shrinkwrap\.json)$' || true
echo
echo "dist package structure in repo:"
git ls-files dist | sed -n '1,20p'
echo
echo "Build output snippets if present:"
for f in dist/cli.cjs dist/cli.js dist/index.js; do
if [ -f "$f" ]; then
echo "--- $f"
sed -n '1,8p' "$f"
fi
doneRepository: linuxhsj/WebModel Length of output: 269 Install the enclosing package metadata with
🤖 Prompt for AI Agents |
||
|
|
||
| runHook postInstall | ||
| ''; | ||
|
|
||
| meta = { | ||
| description = "Bridge web AI models through an OpenAI-compatible API"; | ||
| license = pkgs.lib.licenses.mit; | ||
| mainProgram = "web-model-bridge"; | ||
| }; | ||
| }; | ||
|
|
||
| # ── overlay ─────────────────────────────────────────────────────────── | ||
| overlay = final: _prev: { | ||
| web-model-bridge = mkWebModelBridge final; | ||
| }; | ||
|
|
||
| # ── home-manager module ─────────────────────────────────────────────── | ||
| homeManagerModule = { | ||
| config, | ||
| lib, | ||
| pkgs, | ||
| ... | ||
| }: let | ||
| cfg = config.programs.web-model-bridge; | ||
| in { | ||
| options.programs.web-model-bridge = { | ||
| enable = lib.mkEnableOption "web-model-bridge OpenAI-compatible web AI proxy"; | ||
|
|
||
| package = lib.mkOption { | ||
| type = lib.types.package; | ||
| # Resolved from pkgs, which already has the overlay applied by | ||
| # the consumer — no second nixpkgs instance needed. | ||
| default = pkgs.web-model-bridge; | ||
| defaultText = lib.literalExpression "pkgs.web-model-bridge"; | ||
| description = "The web-model-bridge package to use."; | ||
| }; | ||
|
|
||
| port = lib.mkOption { | ||
| type = lib.types.port; | ||
| default = 3000; | ||
| description = "Port the server listens on."; | ||
| }; | ||
|
|
||
| host = lib.mkOption { | ||
| type = lib.types.str; | ||
| default = "127.0.0.1"; | ||
| description = "Host the server binds to."; | ||
| }; | ||
|
|
||
| configFile = lib.mkOption { | ||
| type = lib.types.nullOr lib.types.path; | ||
| default = null; | ||
| description = "Path to a YAML config file (passed via --config)."; | ||
| }; | ||
|
|
||
| extraArgs = lib.mkOption { | ||
| type = lib.types.listOf lib.types.str; | ||
| default = []; | ||
| description = "Extra arguments to pass to the web-model-bridge CLI."; | ||
| }; | ||
| }; | ||
|
|
||
| config = lib.mkIf cfg.enable { | ||
| # Make the binary available in the user's PATH. | ||
| home.packages = [cfg.package pkgs.google-chrome]; | ||
|
|
||
| # Optionally wire up a systemd user service so the server starts | ||
| # automatically on login. | ||
| systemd.user.services.web-model-bridge = { | ||
| Unit = { | ||
| Description = "web-model-bridge OpenAI-compatible web AI proxy"; | ||
| After = ["graphical-session.target"]; | ||
| }; | ||
| Service = { | ||
| ExecStart = lib.concatStringsSep " " ( | ||
| [ | ||
| "${cfg.package}/bin/web-model-bridge" | ||
| "--port" | ||
| (toString cfg.port) | ||
| "--host" | ||
| cfg.host | ||
| "--no-open" | ||
| ] | ||
| ++ lib.optionals (cfg.configFile != null) ["--config" (toString cfg.configFile)] | ||
| ++ cfg.extraArgs | ||
| ); | ||
| Restart = "on-failure"; | ||
| RestartSec = "5s"; | ||
| }; | ||
| Install.WantedBy = ["default.target"]; | ||
| }; | ||
| }; | ||
| }; | ||
| in | ||
| # ── per-system outputs (packages, devShells, …) ─────────────────────── | ||
| flake-utils.lib.eachDefaultSystem ( | ||
| system: let | ||
| pkgs = import nixpkgs { | ||
| inherit system; | ||
| overlays = [overlay]; | ||
| }; | ||
| in { | ||
| packages = { | ||
| web-model-bridge = pkgs.web-model-bridge; | ||
| default = pkgs.web-model-bridge; | ||
| }; | ||
|
|
||
| devShells.default = pkgs.mkShell { | ||
| buildInputs = [pkgs.nodejs_22]; | ||
| shellHook = '' | ||
| echo "web-model-bridge dev shell" | ||
| echo "Run: npm install && npm run build" | ||
| ''; | ||
| }; | ||
| } | ||
| ) | ||
| # ── system-agnostic outputs ─────────────────────────────────────────── | ||
| // { | ||
| # Conventional overlay output (consumers do: nixpkgs.overlays = [ inputs.web-model-bridge.overlays.default ]) | ||
| overlays.default = overlay; | ||
|
|
||
| # home-manager modules (consumers do: imports = [ inputs.web-model-bridge.homeManagerModules.default ]) | ||
| homeManagerModules.default = homeManagerModule; | ||
| }; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: linuxhsj/WebModel
Length of output: 913
🏁 Script executed:
Repository: linuxhsj/WebModel
Length of output: 885
Separate the branch filters with commas.
Each flow sequence contains one branch pattern:
main feat/multi-account. It does not match either intended branch, so the workflow will not trigger as intended.Proposed fix
Apply the same change to both branch filters.
📝 Committable suggestion
🧰 Tools
🪛 actionlint (1.7.12)
[error] 6-6: character ' ' is invalid for branch and tag names. ref name cannot contain spaces, ~, ^, :, [, ?, *. see
man git-check-ref-formatfor more details. note that regular expression is unavailable. note: filter pattern syntax is explained at https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet(glob)
🤖 Prompt for AI Agents
Source: Linters/SAST tools