npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@x12i/xops

v3.9.0

Published

Repository operating layer for Node.js tools, releases, and code agents

Readme

xops

npm is the native package manager. xops is the operating layer for Node.js repositories: one safe command surface for the work around npm, git, tests, scanners, release, setup, and code agents.

Install once with npm install -g @x12i/xops, then use xops from any package folder, packages root, monorepo root, or workspace root.

xops does not replace npm, git, or the tools already owning their domains. It detects repository state, routes work to the right native owner, plans risky actions, executes approved workflows, and reports what happened.

You can also use xops as your only daily command: native project package-manager and git subcommands pass through directly (for example xops run build, xops status), and xops ask resolves plain-English requests to xops automation, npm/pnpm, or git.

Across the supported tool catalog, the same rule applies. The user calls xops by the work they want done; xops decides which native owner should run. If a missing tool is catalog-marked as seamless — user-space install, no password, no account login, no secret prompt, no privileged write — xops can bootstrap it behind the scenes. For example, xops ask "show parallel branches" resolves to xops repo branches; xops can use GitButler's native branch engine behind the scenes while the user keeps one command surface. The top branch workflow surface includes xops repo diff, xops repo show, xops repo pull-check, xops repo apply, xops repo unapply, xops repo absorb, xops repo reword, xops repo move, xops repo squash, xops repo pr, xops agent git setup, and xops agent mcp. Set XOPS_AUTO_INSTALL_TOOLS=0 to disable seamless tool auto-install. The full contract is documented in docs/seamless-tools.md; positioning notes live in site/narratives.md.

xops serves both humans and code agents, but not in exactly the same interface shape. Humans need readable prompts, explanations, recovery hints, and summarized reports. Agents need deterministic plans, non-blocking approval behavior, stable exit codes, JSON where appropriate, and low-noise output they can route without guessing. The same release engine supports both callers, including legacy xnpm users; the presentation and safeguards adapt to the caller's needs.

The bigger story

npm is not the problem. The release workflow is. That is the wedge xops started with, and the release workflow above — discovery, dependency order, safety checks, publish, push, undo, agent-safe execution — is shipped and described in full below.

Release was only the first broken workflow. The wider problem is that a modern Node.js repository is operated through many tools, many configs, and many safety boundaries — package managers, git, GitButler for parallel/stacked branch workflows, workspaces, test runners, linters, release tools, dependency bots (Renovate/Dependabot), security scanners (Snyk, Trivy, npm audit), API tooling (Postman, Newman, OpenAPI), CI, MaGit (Mongo metadata versioning), utilitix (Mongo utility operations), and deployment/observability configs — with two different kinds of callers: humans and code agents.

xops is the operating layer for Node.js repositories: it detects the supported tools already present, reports what is operable, recommends missing capabilities only when repo evidence supports them, bootstraps seamless user-space tools when safe, and applies non-seamless setup only after explicit approval. Every native tool keeps owning its own domain — xops owns the operating contract between them.

npm installs packages.
git stores source history.
GitButler separates parallel, stacked, and agent-driven branch work.
CI runs jobs.
Renovate and Dependabot open dependency updates.
Vitest, Jest, Playwright, Cypress, and Supertest run tests.
ESLint, Prettier, Biome, Husky, lint-staged, and TypeScript enforce quality.
Snyk, Trivy, npm audit, SBOM, license scanning, and GitHub security workflows scan risk.
Postman, Newman, OpenAPI, Swagger/Redoc, Bruno, and Insomnia describe or test APIs.
MaGit versions Mongo-backed metadata.
utilitix handles Mongo utility operations and local secret aliases.
Deployment and observability tools describe where the app runs and how it is monitored.

Each tool owns its domain.
xops owns the operating contract between them.

Status: the release/publish/safety/security/ask/undo/upstream workflows are shipped today, and the operating-layer surface — xops ops status, xops recommendations, xops recommendations apply, and the tools catalog — is available as the broader repository contract. The site now tells that story directly: release was the proof, not the whole product.

Product naming

| | | |---|---| | Product name | xops | | npm package | @x12i/xops | | Daily command | xops | | Agent MCP command | xops mcp --stdio or xops agent mcp --stdio | | Compatibility aliases | xnpm, xgit, x12i-xops, x12i-npm, x12i-git |


CLI, SDK, and MCP

@x12i/xops now exposes the same operating layer through three official interfaces:

  • CLI: xops for humans.
  • SDK: typed TypeScript functions for scripts, internal tools, CI, dashboards, release bots, and code agents.
  • MCP: xops mcp / xops agent mcp for agent runtimes, IDE agents, and autonomous workflows.
import {
  detectRepository,
  runCheck,
  runAskPlan,
  runValidate,
  runRelease,
  runAiPack,
  listPlaybooks,
  planPlaybook,
  runPlaybook,
  generateArchitectureGraph
} from "@x12i/xops";

import {
  listXopsMcpTools,
  callXopsMcpTool
} from "@x12i/xops/mcp";

import {
  defineXopsPlaybook
} from "@x12i/xops/playbooks";

SDK functions return structured XopsRunResult-style objects with issues, tool runs, recommendations, reports, repository context, duration, and stable status values. That gives agents and automation JSON they can consume without scraping terminal text.

MCP exposes typed tools and read-only resources over stdio by default:

xops mcp --stdio
xops mcp start --stdio
xops agent mcp --stdio
xops agent mcp --http --port 7331 --profile readonly
xops mcp --list-tools
xops mcp --list-resources

MCP tools are registered from day one across xops.repo.*, xops.pkg.*, xops.deps.*, xops.security.*, xops.release.*, xops.ai.*, xops.net.*, xops.system.*, xops.node.*, xops.tools.*, xops.reports.*, xops.playbooks.*, and xops.plan.*. They call xops SDK functions and planners; MCP does not expose unrestricted shell execution as its primary interface.

Risky MCP operations are plan-first and non-blocking. Mutations, publish/release, tool installation, and network exposure scans return structured approval-required or authorization-required results unless the caller supplies explicit approval inputs and an MCP profile that allows the action. System-native tools such as Nmap, Trivy, Semgrep, OSV-Scanner, btop, Glances, and Globalping are not silently installed; MCP returns missing-tool/setup guidance just like the CLI agent mode.

MCP resources include xops://repo/context, xops://repo/package-graph, xops://repo/workspace, xops://tools/catalog, xops://tools/status, xops://playbooks/catalog, xops://playbooks/local, xops://playbooks/<name>/definition, xops://playbooks/<name>/last-plan, xops://playbooks/<name>/last-run, xops://reports/latest, xops://logs/latest, xops://ai/context, xops://ai/manifest, and xops://config/resolved.

Operational playbooks

xops has first-class operational playbooks for repeated repository actions that need parameters, planning, risk metadata, approval behavior, and run reports. The built-in catalog currently includes kill-port, dev-stack, publish-chain, and publish-all.

xops playbooks list
xops playbooks status --json
xops playbooks init dev-stack
xops playbooks init kill-port
xops playbooks init publish-chain
xops playbooks init publish-all
xops playbooks plan kill-port --port 3000 --json
xops playbooks run kill-port --port 3000 --dry-run
xops playbooks run dev-stack --stack jobs --port 3000
xops playbooks run publish-chain --package @scope/app
xops playbooks run publish-all --group core --bump minor
xops playbooks explain dev-stack
xops playbooks validate
xops playbooks doctor
xops play kill-port --port 3000
xops run-playbook kill-port --port 3000

Local playbooks live in .xops/playbooks/. xops playbooks init <name> writes a .mjs definition using defineXopsPlaybook(...) and updates .xops/playbooks/playbooks.json; xops playbooks adopt scripts/foo.mjs --name foo --yes copies an existing script into the playbook catalog. Run artifacts are written to .xops/playbooks/runs/<run-id>.json and .xops/playbooks/runs/<run-id>.md.

Plans include resolved inputs, packages, env files, ports, commands, files, required tools, risks, approval requirements, expected artifacts, and steps. Risk classes are explicit: read-only, local-write, local-process, network-local, network-external, package-install, package-publish, git-mutation, system-mutation, and risk-sensitive.

Playbook SDK functions are exported from @x12i/xops: listPlaybooks, detectPlaybooks, loadPlaybook, planPlaybook, runPlaybook, validatePlaybook, generatePlaybook, explainPlaybook, and adoptPlaybook. Authoring helpers are also available from @x12i/xops/playbooks.

MCP exposes xops.playbooks.list, xops.playbooks.load, xops.playbooks.plan, xops.playbooks.run, xops.playbooks.validate, xops.playbooks.generate, xops.playbooks.explain, and xops.playbooks.adopt.

Repository intelligence

New repository-intelligence command surfaces are read-only by default:

xops check                         # full repository intelligence status
xops architecture status --json    # workspaces, Nx, Turbo, Wireit, moon, dependency-cruiser
xops package-check status          # Publint, Are The Types Wrong, pkgroll, npm pack, release tooling
xops ai-pack status                # Repomix / AI-context packaging support
xops hooks status                  # Lefthook / repo hook orchestration support
xops performance status            # Clinic.js, 0x, why-is-node-running, autocannon, hyperfine
xops net dns example.com           # Node-native DNS lookup, no external install
xops system check --json           # Node-native local system facts
xops security trivy --json         # Uses Trivy if installed; otherwise prints setup instructions
xops net exposure 192.168.1.10 --confirm-authorized
xops tools setup lefthook --dry-run

The expanded catalog detects repository hygiene, package publishing, security, hooks, AI context, release/versioning, monorepo/task graph, and performance/debugging tools including Knip, dependency-cruiser, Sherif, Syncpack, ast-grep, Publint, Are The Types Wrong, pkgroll, license-checker-rseidelsohn, tsx, Biome, Oxlint, Lefthook, Secretlint, Gitleaks, dotenvx, npm/pnpm audit scripts, Repomix, Changesets, release-it, npm-check-updates, Clinic.js, 0x, why-is-node-running, autocannon, hyperfine, Turbo, Nx, Wireit, and moon.

Installing xops installs the operating layer, not every possible native tool. Heavy or privileged tools such as Nmap, Trivy, Semgrep, btop, Glances, Globalping, and OSV-Scanner are never installed by npm install -g @x12i/xops, and xops does not silently install them on first use. The command exists from day one; first use detects the backing tool and either runs a Node-native implementation, offers/uses a safe npm companion path when policy allows, or prints exact setup instructions for system-native and risk-sensitive tools. Agent/CI mode returns a missing-tool or approval-required JSON result instead of blocking on a prompt.

xops ask knows these surfaces too:

xops ask "check repository intelligence"
xops ask "show architecture status"
xops ask "show package publish checks"
xops ask "show ai context pack status"
xops ask "show xops sdk surface"
xops ask "resolve dns for example.com"
xops ask "scan network exposure for 192.168.1.10"
xops ask "start xops mcp server"
xops ask "show xops mcp tools"
xops ask "free the dev ports"
xops ask "start the jobs stack"
xops ask "publish the current package and what it depends on"
xops ask "publish all core packages"

Install

Global install (recommended)

| Platform | Command | |---|---| | Windows | npm install -g @x12i/xops | | macOS / Linux | sudo npm install -g @x12i/xops |

On macOS and Linux, sudo is needed because npm’s default global directory (/usr/local/lib/node_modules) is not writable by a normal user. On Windows, install without sudo.

After installation, xops is available from any folder (xnpm, xgit, x12i-xops, x12i-npm, and x12i-git remain as compatibility aliases):

xops --version

Global installation is the primary workflow. You do not need to install @x12i/xops into every package you manage.

Troubleshooting (xops not recognized, PATH, Git Bash, EACCES cache, doctor hangs): see docs/troubleshooting.md or run:

xops troubleshooting
npx @x12i/xops doctor

Update

| Platform | Command | |---|---| | Any | xops upgrade or xops --upgrade | | Windows | npm install -g @x12i/xops@latest | | macOS / Linux | sudo npm install -g @x12i/xops@latest |

xops upgrade checks npm for the latest release and runs npm install -g @x12i/xops@latest. On macOS/Linux you may still need sudo if the global folder is not writable — xops prints both sudo chown … and sudo npm install -g … fixes when that happens (exit code 3 = environment/permissions, not a package error).

After the xops check, xops upgrade also refreshes seamless companion tools that are already installed, such as GitButler's but CLI. It does not install new companion tools during upgrade just because they are recommended; first use or an explicit setup command handles that.

One-off / CI usage

Without a global install:

npx @x12i/xops --build --test
npx @x12i/xops@latest --build --test --publish --push

Or:

npm exec @x12i/xops -- --build --test

Useful for CI, temporary machines, or developers who prefer not to install globally.

Optional project-level install

Teams that want a pinned version per repository may install locally:

npm install --save-dev @x12i/xops

Then expose scripts such as:

{
  "scripts": {
    "xops": "xops",
    "release:packages": "xops --build --test --publish --push --report"
  }
}

This is optional. The global CLI remains the simplest path.

Requirements

The station must already have these tools installed:

  • Node.js >= 20
  • npm — available in PATH
  • git — required when using --push or --create-git

@x12i/xops does not install Node.js, npm, or git. It does not configure npm login or create tokens.

On startup, the CLI validates that npm is available. If --push is used, git must also be available. If --push is not used, a missing git produces a warning rather than a fatal error.

npm authentication

Installing the CLI itself requires no special handling when @x12i/xops is published publicly.

For publish operations, valid npm authentication must already be configured through npm’s normal mechanisms — usually via .npmrc at the repo root or ~/.npmrc.

xops automatically applies the repo root .npmrc to every package install and publish (package-local → invocation root → git root). You do not need to export NPM_CONFIG_USERCONFIG before running xops in a monorepo.

Example shape:

@x12i:registry=https://registry.npmjs.org/
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
always-auth=true

The CLI never asks for tokens, stores tokens, or prints tokens.

Simplest developer flow

# Install once (macOS / Linux — use sudo)
sudo npm install -g @x12i/xops

# Go to a package folder or packages root
cd /path/to/packages

# Fix dependency specs to npm latest, then install dependencies
xops install

# Or use xops for everyday package-manager/git work in a single package folder
xops run build
xops status

# Full release flow
xops --full-flow

# Monorepo: install all packages, then tiered publish scripts
xops --all install
xops scripts init
xops scripts run all

# Update the CLI later
sudo npm install -g @x12i/xops@latest

On Windows, omit sudo from the install and update commands.

xops uses an isolated npm cache at ~/.cache/xops/npm so installs keep working when ~/.npm has permission issues (older installs that already populated ~/.cache/xnpm/npm keep using that path). If the primary cache is root-owned (from a past sudo xops), xops automatically falls back to ~/.cache/xops/npm-clean and prints a one-line chown fix — you do not need wrapper scripts that export NPM_CONFIG_CACHE. See docs/troubleshooting.md for EACCES fixes, exit codes, and cache details.


Usage

xops [command] [flags]

Compatibility aliases: xnpm, x12i-xops, x12i-npm — same binary as xops, kept working for existing scripts and muscle memory.

xgit — git-first CLI (same package)

@x12i/xops also ships xgit / x12i-git — same engine, git-first ergonomics:

xgit status                    # natural git passthrough (no "git" prefix)
xgit pull --rebase origin main
xgit push                      # plain git push (+ rebase prompt when remote is ahead)
xgit ask "commit and push"     # ask resolves git catalog first

# npm / monorepo cross-support (same commands as xops)
xgit install --all
xgit release --report
xgit validate --fix
xgit npm run build             # explicit npm passthrough

| | xops | xgit | |---|----------|----------| | Primary focus | npm install, publish, validate, release | git status, pull, push, commit | | Natural passthrough | xops git status or xops status | xgit status | | Ask catalog order | xops → npm → git | git → xops → npm | | Monorepo lifecycle | full support | full support (cross-solve) |

Show help (default when run with no arguments):

xops
xops help
xops -h
xops --help

Fix dependency specs to npm latest, then install dependencies:

xops i
xops install

List packages, versions, and local dependency relationships:

xops list
xops ls
xops list --filter "@x12i/*"
xops ls --all

Validate workspace integrity and npm registry versions:

xops validate
xops validate --build          # also run npm run build smoke test
xops validate --fix            # fix deps + overrides; major bumps run build unless --no-build
xops --validate --filter "@x12i/*"

Optional: generate a machine-readable package graph, publish scripts, or agent instructions:

xops map                        # write xops.json (backs up existing to xops.json.bak)
xops scripts init               # create scripts/publish-*.sh + package.json publish:* entries
xops map-to ./custom-graph.json # write to a custom file
xops map-out                    # print JSON to stdout
xops --instructions             # writes xops-*.md files only when you run this
xops --instructions --instructions-dir ./docs
xops agent-deploy-guide         # writes .xops/agent-monorepo-deploy.md for code agents
xops init agent-deploy          # alias
xops agent-deploy-guide --dir docs --force

Check environment and fix common setup issues:

xops doctor
xops troubleshooting
npx @x12i/xops doctor

Run the project package manager or git in the current folder (passthrough):

xops run build
xops status
xops npm outdated
xops git log --oneline -5

Commands

| Command | Description | |---|---| | (no command) | Show usage, flags, and examples | | install, i | Fix dependency specs to npm latest, then install dependencies and requested lifecycle steps | | list, ls | List discovered packages, versions, and local dependency relationships | | validate | Check local dependency integrity and npm registry versions (read-only) | | exports | Check/fix package exports for dual ESM/CJS builds | | release | Full release playbook: fix → install → build → test → publish → push | | playbooks, playbook | Plan, explain, generate, validate, and run operational templates under .xops/playbooks/ | | map | Write inferred package graph to xops.json (backs up existing file to xops.json.bak) | | map-to <path> | Write inferred package graph to a custom file | | map-out | Print inferred package graph as JSON to stdout | | scripts | Publish script helpers: init, list, run <name> [-- args] — see Publish scripts | | upgrade | Install the latest @x12i/xops from npm globally (--upgrade alias) | | upstream | CR/FR issue bridge: submit issues to upstream repos, pull-fix, verify — see Upstream CR/FR bridge and docs/upstream.md | | cursor-init | Write Cursor, Codex, and Claude Code agent rules (optional --hooks) | | agent-init | Alias for cursor-init | | agent-deploy-guide | Write agent monorepo deploy guide (default: .xops/agent-monorepo-deploy.md) | | init agent-deploy | Alias for agent-deploy-guide | | doctor | Check Node/npm/git/xops setup; auto-fix common PATH issues on Windows | | troubleshooting | Print install, PATH, cache, and platform troubleshooting guide | | ask <text> | Resolve plain-English to xops, npm, or git (deterministic) | | npm <args> | Run native npm in the current folder | | git <args> | Run native git in the current folder | | help, -h, --help | Same as running xops with no arguments |

xops i and xops install are equivalent for xops automation. Both align package.json dependency specs to npm latest before installing. Flags can be combined with install, e.g. xops install --build --test.

package-manager and git passthrough

xops can front common project package-manager and git commands so you do not need separate binaries for day-to-day work.

Implicit passthrough — recognized project and git subcommands run natively:

| You run | Equivalent | |---|---| | xops run build | npm run build / pnpm run build | | xops test | npm test / pnpm test | | xops install lodash | npm install lodash / pnpm add lodash | | xops publish | xops publish workflow (npm publish under the hood) | | xops status | git status | | xops push | git push | | xops pull | git pull |

Explicit passthrough — always available:

xops npm run build
xops npm outdated
xops pnpm install
xops git status
xops git diff

Project passthrough uses pnpm when pnpm-lock.yaml, pnpm-workspace.yaml, or packageManager: "pnpm@..." is present. Registry and publish commands stay on npm.

Disambiguation — xops automation vs native tools:

| Input | Routed to | |---|---| | xops install | xops install only (refreshes @x12i/* / @exellix/* at latest; add --fix for in-house version fix) | | xops install --fix-public | xops fix + install including public toolchain deps | | xops install --build | xops automation | | xops install lodash | npm install lodash / pnpm add lodash | | xops install -D typescript | npm install -D typescript / pnpm add -D typescript | | xops list / xops ls | xops package discovery | | xops npm list | npm list | | xops --publish | xops lifecycle publish | | xops publish | xops lifecycle publish (npm publish under the hood) | | xops --push | xops lifecycle git push | | xops push | git push | | xops --test | xops lifecycle test | | xops test | npm test / pnpm test |

Reserved xops commands (ask, doctor, help, list, ls, map, map-to, map-out, scripts, troubleshooting, validate) always stay on the xops side.

Natural-language commands (xops ask)

xops ask lets you describe what you want in plain English. The CLI resolves that text to a normal command — xops automation flags, native project package-manager commands, npm registry commands, or git — using the same execution path you would use directly.

This is not an LLM. There is no model dependency, no local AI setup, and no hallucinated shell commands. Resolution is deterministic: input is normalized and matched against phrase catalogs by @x12i/ask-cli, then turned into a structured plan that is validated before anything runs.

Resolution order: xops catalog first, then npm, then git. xops workflow phrases win when they match.

# xops automation
xops ask "install all packages"
xops ask "install, build and test all @x12i packages"
xops ask "publish all @x12i packages and push"
xops ask "create publishing scripts"
xops ask "run publish script all"
xops ask "create new private npm packages for @exellix packages"

# native package manager / npm registry
xops ask "run build"
xops ask "run tests"
xops ask "show outdated packages"

# native git
xops ask "show git status"
xops ask "pull latest changes"
xops ask "push to remote"

How it works

When you run xops ask "<text>", the CLI:

  1. Normalizes the text (lowercase, trim, collapse spaces, normalize &and, everythingall packages, and similar shorthands).
  2. Matches the normalized input against the phrase catalog (exact phrase first, then slot patterns).
  3. Extracts known variables such as scope (@x12i, exellix), package name, repo mode, or git provider.
  4. Builds a structured argv list (never executes the raw English string).
  5. Validates the plan using the same rules as normal commands (buildOperations, createExecutionPlan, or package-manager/git passthrough).
  6. Shows the resolved command, what it will do, and any risks.
  7. Asks for approval when the operation is dangerous.
  8. Executes only after validation (and approval, if required).

What you can say

The catalog covers common workflows. Phrasing can vary; many aliases resolve to the same command.

| You might say | Resolves to | |---|---| | install all packages | xops | | install all / install everything | xops | | build and test everything | xops --build --test | | install, build and test all @x12i packages | xops --filter "@x12i/*" --build --test | | install, build and test all @x12i and @exellix packages | xops --filter "@x12i/*" --filter "@exellix/*" --build --test | | publish all packages | xops --build --test --publish --report | | publish all @x12i packages and push | xops --filter "@x12i/*" --build --test --publish --push --report | | create new private npm packages for @x12i packages | xops --filter "@x12i/*" --build --test --new-private --report | | push all repos | xops --push --report | | connect git repo to [email protected]:x12i/packages.git | xops --connect "[email protected]:x12i/packages.git" | | link remote [email protected]:x12i/core.git and push | xops --connect "[email protected]:x12i/core.git" --push --report | | create git and connect to [email protected]:x12i/demo.git | xops --create-git --connect "[email protected]:x12i/demo.git" | | run build | xops run build | | run tests | xops test | | show outdated packages | xops npm outdated | | show git status | xops git status | | pull latest changes | xops git pull | | push to remote | xops git push |

Scope names are flexible. All of these filter the same way:

@x12i
x12i
x12i packages
all @x12i packages
packages under @x12i

Approval for dangerous operations

Safe operations (install, build, test, status, diff) run immediately after resolution.

Dangerous operations (publish, push, pull, commit, first-publish, git creation) show a confirmation prompt:

I understood this as:

  xops --filter "@x12i/*" --build --test --publish --push --report

This will:
  - Select packages matching the requested scope.
  - Run install.
  - Run build and test.
  - Publish packages in dependency-aware order.
  - Push git changes.
  - Show a summarized report.

Risks:
  - This may publish new npm versions.
  - This may push commits to git remotes.

Execute? [y/N]

Only y or yes proceeds. Anything else cancels.

Code-agent-safe ask (2.30.0+)

xops ask never blocks on stdin when the caller is a code agent or CI, and offers a plan-only mode for resolving intent without executing anything:

xops ask "release the stack" --plan --json   # resolve only — argv, risks, explanation, suggested --yes command
xops ask "release the stack" --agent         # never prompts; exits 4 if approval is required
XOPS_AGENT=1 xops ask "release the stack"    # same, via env var
CI=true xops ask "release the stack"         # same, detected automatically
xops ask "release the stack" --yes           # explicit approval — executes
  • --plan resolves the request to a command, argv, risks, and explanation, and exits without running it.
  • --json prints that resolution as machine-readable JSON instead of the human-readable summary.
  • --agent, XOPS_AGENT=1, CI=true, or a non-TTY stdin all mean "never wait for an interactive answer."
  • In any of those non-interactive contexts, a dangerous operation without --yes exits with code 4 (approval required) instead of hanging on a prompt that will never be answered. TTY behavior for humans is unchanged.

Unknown requests

If no catalog can match your text, xops ask fails safely and suggests known examples. It does not call an LLM or run arbitrary commands.

I could not match that request to a known xops, npm, or git command.

Try one of these:
  xops ask "install all packages"
  xops ask "run build"
  xops ask "show git status"
  xops ask "publish all @x12i packages and push"

Phrase catalogs ship at:

  • src/catalog/xops-ask.catalog.json — multi-package workflows
  • src/catalog/npm-ask.catalog.json — common npm commands
  • src/catalog/git-ask.catalog.json — common git commands

(built to dist/catalog/). Matching and normalization come from @x12i/ask-cli; xops owns validation, approval, and execution. Covered by automated tests (npm test).

Flags

| Flag | Description | |---|---| | --build | Run npm run build / pnpm run build after install | | --test | Run npm test / pnpm test after build | | --publish | Bump minor version and publish to npm | | --publish-flow | Run fix, install, publish, and push with a final report | | --full-flow | Run fix, install, build, test, publish, and push with a final report | | --push | Commit and push via git | | --no-push | With release, --publish-flow, or --full-flow, skip all git push steps | | --report | Suppress noisy output, show high-level summary only | | --validate | Check local dependency integrity and npm registry versions (read-only; same as validate command) | | --fix | Refresh @x12i/* / @exellix/* (and workspace locals) to ^npm-latest | | --fix-public | Also bump public/third-party deps (vite, react, tailwindcss, …) | | --all-external | Alias for --fix-public | | --force-engine | Allow fix when engines.node would block | | --no-fix | Skip automatic fix on install, --publish, --publish-flow, and --full-flow | | --no-install | Skip npm install steps (use after a local npm install) | | --force-republish | Publish even when the version already exists on npm (default: skip with --no-version-bump) | | --instructions | Write xops-package-graph-instructions.md and xops-package-graph-readme.md for agents (optional) | | --instructions-dir <path> | Output directory for --instructions (default: current folder) | | --dry-run | Show planned execution without modifying files | | --no-version-bump | Publish the current version without bumping | | --clean-local | Remove local file: overrides from package.json | | --clean-all | Remove the entire overrides object from package.json | | --force | Opt-in: npm cache clean --force once before install; on --push, retry with --force-with-lease after rebase recovery is declined or fails | | --fast | Skip some slow checks (tarball inspect, gitignore/npmignore enforcement, post-publish verify, install-health). Pack-check still runs on publish and cannot be disabled — .env / secrets in the tarball are always blocked | | --stack <name> | Load release playbook from .xops/stacks/<name>.json or .yaml | | --with-catalox | Run stack postRelease scripts when .env is present | | --message <text> | Custom release summary for CHANGELOG and git commit ({name}, {version}, {shortName}) | | --all | Discover all packages under cwd, including nested git repos | | --package <name> | Select a specific package (repeatable) | | --filter <glob> | Select packages matching a glob (e.g. @x12i/*) | | --json | Machine-readable output where supported (xops ask --plan --json, xops history --json) | | --plan | xops ask only: resolve to a command/argv/risk plan without executing it | | --agent | xops ask only: never wait for interactive approval (also via XOPS_AGENT=1 or CI=true); exits 4 instead of prompting when approval is required | | --yes | xops ask only: approve a matched dangerous operation non-interactively and execute it |

Creation flags (opt-in)

These flags initialize missing git/npm setup when explicitly requested. Normal commands assume packages and git repositories already exist.

| Flag | Description | |---|---| | --create-git | Create local git repository where needed (git init, initial commit) | | --repo-mode <mode> | monorepo (one root repo) or multi-repo (one repo per package) | | --connect <url> | Alias for --git-link — link folder to an existing remote | | --git-link <url> | Link to an existing remote (monorepo or single package) | | --git-link-template <tpl> | Link remotes by template in multi-repo mode | | --git-map <path> | Link remotes via JSON map file in multi-repo mode (not the same as map / map-to / map-out) | | --git-create-remote | Create a new remote repo via provider API | | --git-provider <name> | github, gitlab, or bitbucket | | --git-org <org> | Organization or user for remote creation | | --git-visibility <vis> | private or public | | --repo-name <name> | Remote repo name (monorepo) | | --repo-name-template <tpl> | Remote repo name template (multi-repo) | | --new-public | First-publish as a public npm package (no version bump) | | --new-private | First-publish as a restricted npm package (scoped names only) |

Package selection

--package selects packages by exact package.json name (repeatable). --filter matches package names using glob syntax (not folder paths).

Examples:

--filter "@x12i/*"        matches all packages under the @x12i scope
--filter "@exellix/*"     matches all packages under the @exellix scope
--filter "@x12i/ai-*"     matches only @x12i packages whose unscoped name starts with ai-
--filter "*gateway*"      matches package names containing gateway

Multiple --filter values are OR-based:

xops --filter "@x12i/*" --filter "@exellix/*"

matches packages from either scope.

--package and --filter are also OR-based when used together.

If no package matches a given --filter glob, the CLI fails with a clear error. A separate folder-path filter may be added later if needed — package-name and path matching are not mixed in one flag.

Examples

# Show help
xops

# Natural-language commands (deterministic resolver)
xops ask "install all packages"
xops ask "install, build and test all @x12i packages"
xops ask "publish all @x12i packages and push"
xops ask "run build"
xops ask "show git status"
xops ask "connect git repo to [email protected]:x12i/packages.git"

# Native package-manager/git passthrough
xops run build
xops test
xops status
xops npm outdated
xops git log --oneline -10

# Environment check and troubleshooting
xops doctor
xops troubleshooting

# Validate workspace and registry versions
xops validate
xops validate --build
xops --validate --filter "@x12i/*"

# Fix dependency versions against npm without installing
xops --fix
xops install --fix-public --dry-run   # public bumps + rationale; blocked if Node engine gap
xops why-upgrade vite
xops validate --fix

# Dependency usage reports
xops deps unused --include-dev
xops deps usage react --format markdown

# Engine floor
xops engines sync
xops doctor

# Scaffold upstream CR/FR workspace
xops init upstream

# File upstream CR/FR to @x12i/xops (after: xops upstream auth login)
xops upstream submit --id FR-XNPM-1 --registry xops
xops upstream submit --file docs/upstream/my-fr.md --package @x12i/xops --repo x12i/npm
xops upstream auth status

# Install only (workspace-aware)
xops install

# Fix dependency versions against npm, then install
xops install --fix

# Optional: generate package graph and agent instructions (no effect until you add xops.json)
xops map
xops map-to ./custom-graph.json
xops map-out
xops --instructions
xops --instructions --instructions-dir ./docs

# Connect folder to an existing remote (--connect is alias for --git-link)
xops --connect [email protected]:x12i/packages.git --repo-mode monorepo --push

# Install only
xops install

# Install and build
xops install --build

# Install, build, and test
xops --build --test

# Publish flow — fix, install, publish, push, final report
xops --publish-flow

# Full flow — fix, install, build, test, publish, push, final report
xops --full-flow

# Release playbook (same as --full-flow; supports --stack for monorepo policies)
xops release
xops release --stack ai-tasks-line --with-catalox --message "Stack release."
xops release --package @x12i/core

# Fast mode — skip slow security checks (see report for skipped steps)
xops install --fast
xops release --stack ai-tasks-line --fast

# Dry run — show plan without executing
xops --full-flow --dry-run

# Publish without version bump
xops --build --test --publish --no-version-bump

# Remove local file: overrides and install
xops --clean-local

# Remove all overrides and install
xops --clean-all

# Scope-based package selection
xops --filter "@x12i/*"
xops --filter "@x12i/*" --filter "@exellix/*"

# Create local git repo at root (monorepo)
xops --create-git --repo-mode monorepo

# First-publish a scoped package as restricted
xops --package @x12i/core --build --test --new-private --report

# Create/publish new private packages
xops --build --test --new-private --push --report

# Create remote repo and publish
xops \
  --package @x12i/core \
  --create-git \
  --repo-mode multi-repo \
  --git-create-remote \
  --git-provider github \
  --git-org x12i \
  --git-visibility private \
  --repo-name-template "{repoName}" \
  --build --test --new-private --push --report

# Create/link git and publish (monorepo)
xops \
  --create-git \
  --repo-mode monorepo \
  --git-create-remote \
  --git-provider github \
  --git-org x12i \
  --git-visibility private \
  --repo-name packages \
  --build \
  --test \
  --new-private \
  --push \
  --report

What it does

Package discovery

Run from a project folder. By default, xops scopes discovery so it does not crawl unrelated sibling repositories:

| Where you run it | Default scope | |---|---| | Inside a git repo | That repository's root | | Inside an npm workspace | The workspace root | | Anywhere else | Current folder only (nested .git directories are skipped) |

Pass --all to scan every package.json under the current folder recursively — including nested git repos. Use this from a shared parent folder that contains multiple independent projects.

cd xentra
xops install              # only packages in the xentra repo

cd ~/projects/x12i
xops install              # nothing (unless a package lives directly here)
xops install --all        # every package under x12i

Generated and irrelevant folders are ignored automatically (node_modules, dist, build, .git, coverage, .next, .cache, etc.).

Supported layouts:

  • Single package folder
  • Root folder with nested packages
  • Monorepo (shared git root)
  • Multiple independent git repositories under one root

Package graph (xops.json) — optional

Nothing changes unless you opt in. xops works exactly as before when xops.json is absent. The file is optional — use it only when a repo benefits from explicit publish order, documented dev/test cycles, or tiered releases. Repos that already have an xnpm.json keep using it (same fallback behavior as the cache and config dirs below) — only new repos get xops.json.

For those cases, add xops.json at the repo root. It is a machine-readable package graph — not a replacement for package.json, but a complement that documents discovery layout, publish sequences, local dependency edges, known cycles, and release profiles.

Generate a starter graph (only when you run a map command):

xops map                        # writes xops.json (backs up existing to xops.json.bak)
xops map-to ./custom-graph.json # writes a custom file
xops map-out                    # prints JSON to stdout

If xops.json already exists, xops map renames it to xops.json.bak first. An existing .bak is overwritten.

Generate agent instructions (optional; only runs when you invoke it):

xops --instructions

This writes:

  • xops-package-graph-instructions.md — step-by-step workflow for creating or updating xops.json
  • xops-package-graph-readme.md — short overview

Only after you place xops.json in the repo does xops pick it up. It searches from the current folder up to the git root and then uses it for list, validate, and lifecycle commands:

You do not need xops.json for discovery. xops finds packages from package.json files (use xops install --all to scan a tree without per-package git remotes). Add xops.json only when you want explicit publish order, release profiles, or documented dev cycles — generate a starter with xops map from the repo root.

  • Publish order from sequences (via the active releaseProfiles entry for project.layout.mode)
  • Relationships from each package.json by default (operations.graphSource defaults to package-json)
  • Private roots excluded via operations.privatePackages
  • Documented dev cycles respected when operations.allowDocumentedDevDependencyCycles is set
  • Fix scope via operations.autoFix and operations.fix (disable devDependency bumps, exclude toolchain packages)

xops list and validate warn when xops.json dependency metadata is out of sync with package.json (run xops map from the repo root to refresh). Lifecycle runs show the loaded config path when xops.json is in use. Without xops.json, behavior is unchanged: xops infers relationships directly from each package.json.

Set operations.graphSource to "xops.json" only if you intentionally want relationships to follow the graph file instead of live package.json (legacy).

For npm workspace monorepos (workspaces in root package.json), xops runs npm install once at the repo root so local @scope/* siblings link correctly, then skips per-package installs under that root. This avoids registry lookups for unpublished workspace packages. Prefer a single root package-lock.json (nested member locks are warned). Folder-scoped / --here installs under a workspace pass npm install --no-workspaces so npm does not reload the full workspace arborist tree. On Windows lock / arborist failures, see docs/troubleshooting.md.

map / map-to / map-out and --git-map are different: the map commands export the package dependency graph; --git-map links git remotes in multi-repo creation mode.

Publish scripts (xops scripts)

Tiered publish scripts for monorepos — generate once, run by name, forward args to the underlying xops command.

Create scripts (writes scripts/publish-*.sh, wires root package.json, merges into xops.json if present):

xops scripts init          # alias: xops scripts create

| Script name | Shell file | Underlying command | |---|---|---| | preflight | scripts/publish-preflight.sh | xops validate | | core | scripts/publish-core.sh | xops --build --test --publish --report | | all | scripts/publish-all.sh | xops release --report |

Ordered publish runbook (for agents or manual npm publish — discovers packages, dependency order, verify loop):

xops scripts init runbook
xops scripts init runbook --filter "@x12i/memorix-*"   # publish subset; verify all packages
xops scripts init runbook --dry-run                    # preview markdown
xops scripts init all                                # tiered scripts + runbook

Creates:

| File | Purpose | |---|---| | scripts/publish-runbook.md | Step-by-step guide: npm preflight, build + npm publish per package, verify loop | | scripts/publish-ordered.sh | Executable version of the same flow |

List and run:

xops scripts                 # list (same as xops scripts list)
xops scripts run preflight   # validate before publish
xops scripts run core        # build, test, publish in dependency order
xops scripts run all         # full release playbook
xops scripts run all -- --dry-run   # forward extra args after --

Script definitions are read from xops.jsonscripts (populated by xops map) or inferred from root package.json publish:* entries. Commands run from the git repo root with repo .npmrc applied automatically.

xops ask "publish everything in the right order" resolves to xops --build --test --publish --report — install, build, test, and publish each package in dependency order, refreshing dependents to @latest after each publish in the same run.

Typical monorepo flow:

xops map                     # optional: write xops.json graph
xops scripts init            # create publish scripts
xops --all install           # bootstrap all packages
xops scripts run preflight   # validate
xops scripts run all         # release when ready

No wrapper script is required for cache or npmrc — xops handles both. See npm cache and npmrc resolution.

Dependency-aware execution order

Local package relationships are mapped automatically. If @x12i/api depends on @x12i/core, then @x12i/core is installed, built, tested, and published first. Dependency cycles are detected and reported before any commands run.

Releasing from a subfolder: When you run lifecycle commands from sub-folder-b/ (install, build, test, publish, or release), xops walks to the git root, finds sibling packages (e.g. @scope/package-a in folder-of-package-a/), and compares their local package.json version to what you declared in package-b. If the sibling is ahead of your range or not published on npm yet, xops:

  1. xops install / build / test — proactive alert (fast check; does not block). Use xops install --fix to bump declared ranges when appropriate.
  2. xops validate — reports sibling-release-first (error)
  3. xops release / publish — asks permission to release upstream packages first (default yes), or continue without changes (--yes skips prompts)
cd root-folder/sub-folder-b
xops install --package @scope/package-b   # alerts if package-a is ahead / unpublished
xops validate --package @scope/package-b  # check without publishing
xops release --package @scope/package-b     # offers to release package-a first

Use xops release --package @scope/package-a from the repo root or that package's folder when prompted.

If you have added xops.json, publish order and release metadata come from the graph file; local dependency edges still follow each package.json unless you set operations.graphSource to "xops.json". Repos without xops.json are unaffected.

Operation order

For each package:

[fix] → install → build → test → publish → push

fix runs by default only for --publish-flow and --full-flow, or when --fix is passed (e.g. xops install --fix). Use --no-fix to skip it. Set operations.autoFix: false in xops.json to disable fix on flows unless --fix is explicit.

Default fix scope (CR-XNPM-1): --fix refreshes in-house @x12i/* and @exellix/* only. Public toolchain bumps require --fix-public (or name packages explicitly: xops install --fix vite). Prerequisites (Node engine, companion packages) are checked before writes; use --force-engine to override engine blocks.

Only the requested operations run.

By default, install runs npm install only. Pass --force to run npm cache clean --force once before all installs — useful when stale cache entries cause confusing npm resolution errors. If cache clean fails (for example root-owned files in ~/.npm), xops warns once and continues with install.

During every install, xops also runs npm install <pkg>@latest for scoped registry dependencies:

  • always for @x12i/* and @exellix/*
  • for any other scope that appears on a package being handled in the run (for example @acme/* when @acme/app is selected)

Local sibling packages discovered in the same run are skipped (they stay linked locally). After a publish in the same run, dependents still refresh those published packages to @latest.

With --push, if git push fails because the remote has commits you don't have locally, xops shows the missing remote commits and asks to run git pull --rebase origin <branch> then push again (default yes). Pass --yes to approve rebase recovery non-interactively. --force still enables git push --force-with-lease only if rebase recovery is declined or fails. Missing upstream is fixed automatically with git push -u origin <branch>.

Git behavior

Monorepo — all npm lifecycle steps run across all packages first, then git add / commit / push runs once at the repository root.

Multi-repo — each package/repo completes its full lifecycle (including push) before moving to the next.

If there are no git changes to commit, the CLI reports it and continues rather than failing.

Publish behavior

With --no-version-bump, xops checks npm before publishing each package. If that version is already on the registry, the package is skipped (same as a shell npm view pkg@version guard). Use --force-republish to override.

Before publishing any package, the CLI:

  1. Ensures .gitignore covers .env* and .npmrc at the git root (patches missing rules; fails if still incomplete). xops doctor / xops doctor --fix check the same rules.
  2. Validates .npmignore covers .env* and .npmrc (creates one if missing)
  3. Runs npm pack --dry-run --json and fails if any .env or .npmrc file would be included
  4. Bumps the minor version (npm version minor --no-git-tag-version) unless --no-version-bump is set
  5. Runs a second npm pack --dry-run --json on the final package state
  6. Publishes (npm publish --access public)
  7. Updates dependent packages to @latest for dependencies published earlier in the same run (in addition to the scoped @latest refresh that runs on every install — see Operation order)

The pack check is the real safety net — it runs even when ignore files appear correct, because the files field in package.json can override them.

Env file helpers (never print secret values unless you opt in):

xops env status              # which env/secrets tools are signaled
xops env sync                # dry-run: merge root .env keys into package .env (local wins)
xops env sync --write        # apply the merge
xops env report              # key map + conflict flags (values redacted)
xops env report --show-values --json

Fix configuration (xops.json)

Pin toolchain versions or disable automatic fix for lifecycle flows:

{
  "operations": {
    "autoFix": false,
    "fix": {
      "dependencies": true,
      "devDependencies": false,
      "peerDependencies": false,
      "exclude": ["typescript", "@types/node"]
    }
  }
}

Recommended monorepo publish workflow

When versions are pre-aligned and local npm install / build / test already passed:

xops validate --filter "@x12i/*"
npm install && npm run build && npm test
xops --filter "@x12i/*" --no-fix --no-install --publish --no-version-bump --report

npmrc resolution

For each package, xops picks one .npmrc in this order:

  1. If the package folder has .npmrc, use it
  2. Otherwise use the invocation root .npmrc (the folder you ran xops from)
  3. Otherwise use the git-root .npmrc when the repo is a git checkout
  4. Otherwise rely on the system npm configuration (~/.npmrc)

Root .npmrc is passed via NPM_CONFIG_USERCONFIG for install, pack checks, registry validation, and publish — it is never copied into package folders and the token is never printed. In a monorepo, run xops install from the repo root (or rely on git-root fallback) so registry tokens in the root .npmrc apply to every package — a personal ~/.npmrc must not override repo auth.

You do not need to export NPM_CONFIG_USERCONFIG before xops when the repo root has .npmrc; xops sets it automatically per package.

If the workspace root package.json is itself a public package (private !== true, valid name and version), xops release --package <root-name> can publish it even when workspaces is defined. Set "xops": { "publishRoot": false } to force the traditional private-root behavior.

npm cache

xops uses an isolated cache at ~/.cache/xops/npm for every npm subprocess (install, publish, passthrough xops npm …, upgrade checks, and so on).

| Situation | xops behavior | |---|---| | ~/.npm not writable (past sudo npm) | One-line notice; xops uses its own cache | | ~/.cache/xops/npm root-owned | Auto-fallback to ~/.cache/xops/npm-clean + prints chown fix | | NPM_CONFIG_CACHE set and writable | Respected (your explicit cache wins) | | Both caches unusable | Exit 3 (environment) before install with clear fix steps |

You do not need shell wrappers that export NPM_CONFIG_CACHE for normal project work.

Clean modes

--clean-local removes only overrides that point to packages discovered in the current run (e.g. "@x12i/core": "file:../core"), leaving unrelated overrides intact.

--clean-all removes the entire overrides object.

If overrides are modified, a second npm install runs automatically so package-lock.json and node_modules reflect the change.

There is no --clean. Using it is an error. Using both --clean-local and --clean-all together is also an error.

Override / direct-dependency conflicts

xops runs npm install <pkg>@latest for scoped registry dependencies (@x12i/*, @exellix/*, and scopes from workspace package names). npm rejects root-level overrides on packages that are also direct dependencies unless the override uses the $ reference form or exactly matches the direct dependency spec after @latest refresh.

Detection: xops validate and xops doctor report override-latest-conflict, override-spec-mismatch, and override-redundant findings before npm is invoked.

Auto-fix: xops validate --fix or xops install --fix (and publish flows with fix enabled) remove redundant overrides by default, or convert them to $@scope/pkg when operations.overrideFix.prefer is use-reference or the key is listed in operations.overrideFix.keepPatterns.

Example xops.json:

{
  "operations": {
    "autoFixOverrides": true,
    "overrideFix": {
      "prefer": "remove-when-direct-dep",
      "keepPatterns": ["nanoid"]
    }
  }
}

| Key | Default | Meaning | |---|---|---| | autoFixOverrides | true when --fix / publish-flow; else false | Auto-apply on install pre-flight | | overrideFix.prefer | remove-when-direct-dep | Default strategy when multiple apply | | overrideFix.keepPatterns | [] | Override keys never auto-removed (exact match or * suffix glob) |

Manual fix for a conflicting override on a direct dependency:

"overrides": {
  "@x12i/graphenix-core": "$@x12i/graphenix-core"
}

Or remove the override entry when it matches the direct dependency spec.

Tarball inspection gate (pre-install)

Before npm install, xops inspects new registry dependency tarballs for Phantom Gyp–style attacks (malicious binding.gyp shell substitution, decoy root index.js, fake native addons). Inspection runs in memory — nothing is written to disk except the audit log and cleared cache.

| Check | Code | What it detects | |---|---|---| | A | PHANTOM_GYP | binding.gyp with <!(...) shell command substitution | | B | OVERSIZED_DECOY | Root index.js > 1 MB and > 10× declared main size | | C | PHANTOM_GYP_NO_NATIVE_SRC | binding.gyp with no .c/.cc/.h source files |

Skipped when: same version already in node_modules, package cleared in ~/.xops/inspected.json with matching integrity hash, name is in the bundled trusted catalog (~1000 common unscoped packages, built from npm’s top ~2000 by search popularity), scope is in the bundled trusted catalog (~200 vendor orgs including @x12i, @exellix, @types, @nestjs, @vitejs, …), or scope is user-configured in ~/.xops/config.json (older installs that already have ~/.xnpm/config.json keep using that path until you migrate).

Unknown components only: scoped packages outside the bundled and user lists are still inspected (e.g. a new @acme-corp/* dependency).

Regenerate bundled lists: npm run generate:trusted-catalog (fetches top 2000 npm names, splits scoped → vendors / unscoped → packages; pins in scripts/trusted-catalog-pins.json are always kept).

Tradeoff: allowlisted packages skip inspection even if a mainstream name is compromised. Use --force to re-scan everything; integrity hash changes still trigger re-inspection.

Re-inspected when: version changes, --force, or tarball integrity hash differs from cache (republished package).

On warning, xops prompts [y/N]. In CI (CI=true or non-TTY), default is abort (exit 1). User overrides are logged to ~/.xops/audit.log.

xops install                      # inspect new deps, then install
xops install --inspect-only       # inspect only (CI pre-flight)
xops install --skip-inspect       # skip gate (debug; logs warning)
xops install --force              # re-inspect all (including trusted scopes)

xops config trust-scope @mycompany
xops config untrust-scope @mycompany
xops config list-trusted-scopes

xops audit --log                  # full inspection audit log (NDJSON)
xops audit --log --overrides      # user-overridden warnings only

Cleared cache schema (~/.xops/inspected.json):

{
  "version": 1,
  "entries": {
    "[email protected]": {
      "integrity": "sha512-…",
      "clearedAt": "2026-06-13T10:00:00Z",
      "userOverride": false
    }
  }
}

Additional trusted scopes live in ~/.xops/config.json:

{ "trustedScopes": ["@mycompany"] }

Background: Phantom Gyp and the CVE gap (June 2026)

In June 2026, the Miasma worm spread through npm using a technique researchers call Phantom Gyp: a malicious binding.gyp that triggers node-gyp rebuild during npm install — with no preinstall or postinstall entry in package.json. Snyk tracked the incident as Node-gyp Supply Chain Compromise — June 2026, covering 57 affected packages across hundreds of malicious versions, all classified as Embedded Malicious Code at Critical severity — Snyk's own advisory system, not a CVE.

There is no CVE for the technique itself, and that is fundamental to how CVEs work. A CVE describes a vulnerability in specific software — a bug in npm, a flaw in node-gyp, a bad default. Phantom Gyp does not exploit a bug. Attackers weaponized gyp's <!(...) command substitution, which is working as designed. There is nothing to patch in npm or node-gyp; the feature is intentional. The same pattern applies to most supply-chain attacks: individual compromised packages get npm security advisories, but the technique of using binding.gyp to execute code does not get a CVE because npm is not broken.

| Layer | What it catches | Phantom Gyp gap | |---|---|---| | npm security advisories | Known-bad package versions (after filing) | Reactive — misses the window before advisories exist | | npm audit | Packages with published advisories | Same — no proactive structural check | | --ignore-scripts | preinstall / postinstall / lifecycle hooks | Does not stop node-gyp rebuild triggered by binding.gyp (Snyk) | | xops tarball inspection | <!( in binding.gyp, decoy payloads, fake native addons | Structural — catches the technique before install, even with no advisory yet |

The reliable defenses Snyk and others recommend are: pin to known-good versions, and scan tarballs before building. That is exactly what this gate does. It would have flagged these packages during the ~two-hour window when malicious versions were live but before any advisory existed — the gap no advisory database fills.

Run logs (.xops/logs/)

Every xops run writes a log under .xops/logs/ in the project (gitignored; falls back to .xnpm/logs/ in projects that already use that folder). On completion, stderr prints the path; with --report or --dry-run, the summary footer includes it too. On failure, the message points at the full log for debugging.

.xops/latest-log.json points at the most recent log. Lifecycle runs with transaction journaling reuse the transaction id as the log filename.

Release playbooks (.xops/stacks/)

For monorepos with per-package test commands, version policies, changelog templates, and post-release hooks, add stack files at .xops/stacks/<name>.json or .yaml, then:

xops release --stack <name>
xops ask "release stack <name>"

Stack config can set per-package test, versionPolicy, publish, changelog, postRelease, and dependsOn ordering. See tests/fixtures/stacks/ for an example shape.

dependsOn is honored as the release order even when package.json does not contain every operational edge — publish order is a release contract, not just a runtime import graph:

{
  "stack": "jobs-reliability",
  "syncInternalDepsOnPublish": true,
  "restoreFileDepsAfterRelease": true,
  "packages": [
    { "path": "jobs-db", "name": "@exellix/jobs-db", "versionPolicy": "patch" },
    {
      "path": "jobs",
      "name": "@exellix/jobs",
      "dependsOn": ["@exellix/jobs-db"],
      "versionPolicy": "patch"
    }
  ]
}

With syncInternalDepsOnPublish: true (2.30.0+), xops rewrites in-stack local dependency specs (file:, link:, workspace:) to ^<publishedVersion> immediately before a downstream package's publish step, using the version just published earlier in the same stack run — then restores the original local spec afterward (restoreFileDepsAfterRelease, defaults to true when sync is enabled). Local development keeps file: links; the published package only ever sees a real registry range. This only rewrites in-stack internal deps, not every file: dependency in the package.

Validate install health (post-upgrade checks)

When node_modules is present, xops validate also checks:

| Finding code | Meaning | |---|---| | engine-node-unsupported | Installed package engines.node not satisfied by current Node | | engine-node-warn | Possible Node engine mismatch (e.g. Vite 8 on Node 22.11) | | native-binding-missing | Platform native binding missing (e.g. Rolldown on Windows) | | migration-config-stale | Known breaking upgrade config hint (Tailwind 4, Vite 8) | | build-smoke-failed | project build script failed during --build or post-fix smoke | | dependency-patched | Consumer patch detected (patches/, pnpm.patchedDependencies, or patch-package script) |

xops validate --build        # run project build script and fail validate on error
xops validate --unused-deps    # warn on unused direct dependencies
xops validate --report-patches # validate, then file upstream CRs for detected patches
xops validate --fix            # after major dep bumps, runs build smoke by default
xops install --fix             # in-house @x12i/* / @exellix/* only
xops install --fix-public      # opt-in public toolchain bumps (prerequisite pass)
xops install --fix vite        # explicit package list only

Consumer dependency patches

xops validate warns on patches but never removes them. --fix and install flows are unchanged.

Detects patches/*.patch (patch-package), pnpm.patchedDependencies, and patch-package lifecycle scrip