JSPM

@fendsh/cli

0.1.0-alpha.2
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 6
  • Score
    100M100P100Q72343F
  • License MIT

Fend off risky dependencies. Sandboxed runtime for package installs and dev scripts.

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@fendsh/cli) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    CI npm downloads License: MIT Platform: macOS%20arm64 Status: alpha

    fend

    Fend off risky dependencies. A sandboxed runtime for npm install and friends.

    npm install still runs arbitrary third-party code as your user, and recent supply-chain attacks have shown how little friction that takes in practice. Incidents around packages used by teams depending on Axios, Bitwarden CLI, and SAP's Mini Shai-Hulud demonstrate the same pattern: once install-time code executes on the host, secrets and developer environments are in scope. Existing tooling mostly catches known bad packages after the fact. Fend takes the opposite approach and assumes package execution is hostile by default.

    fend npm install        # runs npm install inside a micro-VM
    fend npm run dev        # dev server is sandboxed too; ports forward back
    fend audit              # OSV.dev advisory check across the lockfile
    fend audit --fix        # propose + apply safe upgrades

    Status: alpha. macOS Apple Silicon is the only released platform today — npm install -g @fendsh/cli gets you a Developer ID signed and Apple notarized binary. The Swift CLI, the Rust guest agent, the warm-VM daemon, port forwarding, the shell hook, and the audit flow all work end-to-end. Linux x86_64 has a working Rust path in the repo (real QEMU/KVM validation on Arch, runtime bootstrap, port forwarding, npm pack/install) but is not yet published. Windows remains roadmap-only.


    Why

    When you run npm install, any package can define preinstall/postinstall scripts that execute arbitrary code with your full user permissions. A rogue dep can silently read ~/.ssh/id_rsa, ~/.aws/credentials, scan for .env files, install background processes, hit the macOS Keychain — anything your account can touch.

    npm audit only catches known CVEs. Node's experimental permission model is opt-in and unused. macOS protects system files but your home directory — where the valuable stuff lives — is wide open.

    fend assumes everything is hostile and isolates execution from your machine. Your code stays native and you edit it normally. The moment something needs to executenpm install, npm run dev, npm test — it runs inside a lightweight micro-VM with VirtioFS access to only the project directory. Nothing else on your machine is reachable.

    This is the browser security model applied to local development.


    Quickstart

    Requires macOS 13+ on Apple Silicon and Node.js 18+ for the npm install path.

    # install — signed and Apple notarized binary
    npm install -g @fendsh/cli
    
    # first run auto-prepares the guest runtime (~1.5 GB, one-time, cached in
    # ~/.fend/runtime/ after that)
    fend npm install
    
    # everything else is just `fend <command>`
    fend npm run dev        # dev server runs in the VM, port 3000 forwards to host
    fend npm test
    fend node scripts/seed.js
    fend --network off npm test

    Verify the install:

    fend --version          # 0.1.0-alpha.2
    fend doctor             # checks kernel, runtime, daemon, config

    Shell hook (no prefix)

    If you don't want to type fend every time, install the shell hook:

    # zsh
    echo 'eval "$(fend hook zsh)"' >> ~/.zshrc
    
    # bash
    echo 'eval "$(fend hook bash)"' >> ~/.bashrc
    
    # then in any project
    cd my-project
    fend on                  # npm/bun/pnpm/yarn/node/python now route through fend
    npm install              # sandboxed
    npm run dev              # sandboxed
    fend off                 # back to normal

    Audit

    fend audit queries OSV.dev for advisories against everything in your package-lock.json and prints a unified report:

    fend audit               # report only
    fend audit --fix         # apply safe in-range upgrades + overrides
    fend audit --fix --force # also apply major-version bumps
    fend audit --json        # structured output for CI

    The audit also runs automatically before fend npm install. Findings show up as:

    warn  3 advisories found  worst HIGH
      packages  2 of 412 packages
      duration  1.1s
    
    Package   Current  Fix                 Worst     Advisories
    minimist  1.2.0    1.2.6 override      HIGH      GHSA-xvch-5gv4-984h
    lodash    3.10.1   4.17.21 needs --force CRITICAL GHSA-jf85-cpcp-j695
    
      HIGH minimist: Prototype pollution in minimist [GHSA-xvch-5gv4-984h]
      CRITICAL lodash: Prototype pollution in defaultsDeep [GHSA-jf85-cpcp-j695]
    
    info  fix plan  1 auto-fixable, 1 major bump (--force)

    Planned: AI-assisted package review

    Fend's install flow is designed to support a future AI review gate between npm install --ignore-scripts and npm rebuild: install packages without lifecycle scripts first, collect evidence about risky/new/scripted packages, ask an AI reviewer for a structured verdict, then decide whether scripts should run.

    The first integration target is agent-ws, a local WebSocket bridge for Claude Code and Codex CLI. That keeps provider tokens outside Fend by default and lets users reuse their existing CLI agent authentication. The intended role is advisory/gating support — AI can explain and flag suspicious dependency behavior, but it cannot prove a package is safe.

    Likely review inputs:

    • new or changed packages from the lockfile
    • lifecycle scripts (preinstall, install, postinstall, prepare)
    • selected package files such as package.json and install scripts
    • OSV audit findings
    • network and filesystem evidence from the sandbox

    Possible future config shape:

    [ai]
    enabled = false
    provider = "agent-ws"               # agent-ws | openai | anthropic
    url = "ws://localhost:9999"
    token_env = "FEND_AGENT_WS_TOKEN"
    mode = "report"                     # report | warn | block
    scope = "risky"                     # risky | new | direct | all
    max_packages = 25

    Run Claude Code sandboxed

    fend claude              # runs `claude` with your Anthropic OAuth token injected,
                             # nothing else from your machine reachable
    fend claude <cmd>        # run anything else with the same env

    Configuration

    Drop a .fend.toml at the project root. Every field is optional.

    [runtime]
    node = "22"                          # pin the Node version inside the VM
    bun  = "1.1"
    
    [vm]
    cpus = 2
    memory = "2GB"
    
    [network]
    mode = "on"                         # on | off
    
    [watch]
    mode = "auto"                       # auto | native | polling | mirror
    poll_interval_ms = 500              # used when polling is active
    
    [audit]
    level = "strict"                     # strict | warn | off
    rebuild = true                       # run `npm rebuild` after a clean audit
    auto_approve_in_ci = false           # skip prompts when $CI is set
    block = ["malware", "critical"]      # severities that halt the install
    prompt = ["high"]                    # severities that require y/N confirmation
    fix_on_install = true                # offer to apply safe fixes before install
    include_prerelease = false           # consider pre-release versions when fixing

    Generate one with fend init.

    Use mode = "off" or fend --network off <command> for commands that should not reach the internet, such as tests or risky install-script rebuilds. The network mode is recorded in fend log for later review.

    [watch] controls file-change detection for long-running dev servers. Today auto keeps macOS on native VirtioFS notifications and switches likely Linux dev commands to polling for compatibility with current VirtioFS host-to-guest watcher limits. You can override one command with fend --watch polling npm run dev or force native behavior with fend --watch native npm run dev. mirror is reserved for the planned Linux mode where host source files are copied into a disposable guest-local workspace for better HMR behavior.

    Useful log filters:

    fend log --network off
    fend log --network-events
    fend log --fs-risk high
    fend log --audit-decision blocked
    fend log --failed

    Use fend log --json to inspect structured filesystem and network evidence for a specific run.

    Terminal output

    Human output is intentionally compact: status labels, small tables, and hints for common failure modes. Guest command stdout/stderr is passed through unchanged so tools like npm, node, and test runners still behave normally.

    Useful environment controls:

    NO_COLOR=1 fend npm test          # disable ANSI colors
    FEND_VERBOSE=1 fend npm run dev   # include daemon/debug status lines
    FEND_QUIET=1 fend npm test        # suppress non-warning host status
    FEND_FORCE_COLOR=1 fend log       # force color even when auto-detection says no

    How it works

    fend <command> wraps any shell command in a sandboxed VM. On macOS that's Apple's Virtualization.framework running a stripped-down Linux with VirtioFS for the project directory mount. The first invocation per project boots a VM (~1s); subsequent invocations reuse a warm VM (auto-paused after 5 minutes idle).

    A small Rust binary (fendd) runs as PID 1 inside the VM, talks to the host over virtio-vsock, manages port forwarding, and supervises the user's command.

    The VM can read/write the project directory and, by default, reach the network. Per-command network access can be disabled with --network off. It cannot see ~/.ssh, ~/.aws, ~/Library, ~/.gnupg, .env files outside the project, or any other path on the host.

    For deep architecture detail — VM lifecycle, scenarios, file-watching/HMR strategy, VirtioFS performance, system diagrams — see ARCHITECTURE.md.


    Build from source

    You'll need Xcode 15+ (Swift 5.9+), Rust, and Docker.

    # Swift CLI + daemon (ad-hoc signed for local dev)
    FEND_AD_HOC=1 ./scripts/build-binary.sh
    swift/.build/release/fend --help
    
    # Rust guest agent (cross-compiled to aarch64-musl, baked into the rootfs)
    cd fendd && cargo build --release --target aarch64-unknown-linux-musl
    
    # Run tests
    swift test --package-path swift
    cargo test --manifest-path fendd/Cargo.toml

    On macOS, the first fend <anything> call runs swift/scripts/prepare-runtime.sh and prepares ~/.fend/runtime/. On Linux x86_64, the Rust binary now owns that flow: fend setup prepares ~/.fend/runtime/linux-x86_64, and normal fend <command> runs bootstrap it automatically when needed.

    Packaging for npm

    scripts/build-binary.sh stages the macOS Apple Silicon binary into packages/cli-darwin-arm64/bin/, signing with Developer ID + hardened runtime

    • RFC 3161 timestamp + Apple notarization by default. Set FEND_AD_HOC=1 for local dev (no Developer ID needed) or FEND_SKIP_NOTARIZE=1 to skip the Apple submission round-trip while iterating.

    scripts/build-linux-binary.sh stages the Linux x64 host fend binary plus the packaged fendd guest agent into packages/cli-linux-x64/. The JS wrapper at bin/fend.js resolves the right platform package via npm's optionalDependencies, falling back to monorepo artifacts during local development.

    For local release verification:

    • ./scripts/pack-npm.sh --platform darwin-arm64 builds/stages binaries and emits the root + platform .tgz packages.
    • ./scripts/publish-npm.sh --platform darwin-arm64 --dry-run checks the publish order and package contents without touching the registry.

    The tag-triggered .github/workflows/release.yml runs the same flow in CI with npm Sigstore provenance attached (docs/RELEASING.md documents the required GitHub secrets and the full release procedure).


    Roadmap

    • Fend is focused on a solid macOS Apple Silicon alpha first: npm distribution, Developer ID signing, notarization, and real-project soak.
    • macOS Intel is the next platform candidate after the Apple Silicon alpha is stable.
    • Linux host work is active in Rust under linux/, but the release path is still macOS-first today.
    • Windows and AI-assisted review remain future work.

    See docs/ROADMAP.md for the roadmap summary and docs/linux-backend.md for the detailed Linux plan.

    Issues, bug reports, and PRs welcome.


    Security

    Fend is a security tool, so the repo treats supply-chain and disclosure hygiene as part of the product. Signed commits, branch protection, and private vulnerability disclosure are part of the expected release process. See SECURITY.md for the reporting policy and response expectations.

    Contributing

    If you want to contribute, start with CONTRIBUTING.md for build/test expectations and CODE_OF_CONDUCT.md for the community ground rules. Small, focused PRs with tests and relevant docs updates are the easiest to review.


    License

    MIT — see LICENSE.


    Acknowledgements

    Standing on the shoulders of: