agentinel 0.0.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +196 -70
  2. package/dist/asen.js +36 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,104 +1,230 @@
1
- # agentinel
1
+ <div align="center">
2
+ <img src="assets/banner.jpg" alt="Agentinel Banner" width="100%" />
2
3
 
3
- Guards your AI coding agent when it installs npm packages.
4
+ [![npm version](https://img.shields.io/npm/v/agentinel.svg?style=flat-square)](https://www.npmjs.com/package/agentinel)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](LICENSE)
6
+ [![Node.js CI](https://img.shields.io/github/actions/workflow/status/aman-janwani/agentinel/publish.yml?style=flat-square)](https://github.com/aman-janwani/agentinel/actions)
7
+ [![Tested On](https://img.shields.io/badge/Tested_On-macOS_%7C_Linux_%7C_Windows-success?style=flat-square)](#)
8
+ </div>
4
9
 
5
- Coding agents install dependencies on your behalf, often without you looking closely. Sometimes
6
- they install a package that was registered last week with no history, sometimes one whose name they
7
- invented, and sometimes a legitimate package that pulls in a compromised one three levels deep.
8
- agentinel checks every package an install would bring in, at the moment the agent reaches for it,
9
- and tells the agent why something looks wrong so it can back off.
10
+ <br />
10
11
 
11
- Every other tool in this space guards your terminal. agentinel guards your agent.
12
+ > **The zero-cost, locally-run package guardrail for your AI coding agents.**
12
13
 
13
- ## Install
14
+ *Agentinel guards your AI agent when it installs npm packages, catching hallucinated dependencies, slopsquatting, and malicious packages before they execute on your machine.*
15
+
16
+ ---
17
+
18
+ ## 📖 The Problem
19
+
20
+ AI coding agents (like Claude Code, Copilot, or Cursor) install dependencies on your behalf, often while you aren't looking closely.
21
+ - Sometimes they install a package that was registered last week with no history.
22
+ - Sometimes they install a package whose name they entirely **hallucinated**.
23
+ - Sometimes, they install a legitimate package that pulls in a compromised one three levels deep.
24
+
25
+ **Agentinel** checks every package an install would bring in, at the exact moment the agent reaches for it. It evaluates the package against a bundled, locally-run database of over 216,000 known malicious packages and zero-cost registry heuristics. It then tells the agent why something looks wrong so the AI can back off and reconsider.
26
+
27
+ Every other tool in this space guards your terminal. **Agentinel guards your agent.**
28
+
29
+ ---
30
+
31
+ ## ⚡ Features & Security Philosophy
32
+
33
+ - **Zero-Cost & Private:** Agentinel does no network interception, runs no cloud proxies, and requires no paid APIs. The malware list is matched locally.
34
+ - **Deep Tree Scanning:** Checks every package an install would *actually* bring in, not just the one named. (`npm install express` brings in 67 packages. We check all 67).
35
+ - **Known Malware:** Bundles a local OSV database of 216,000+ confirmed malicious packages.
36
+ - **Zero False Positives on Popular Packages:** Tested against the top 100 npm packages.
37
+ - **Heuristic Scanning:** Flags npm takedowns, packages under 30 days old with < 1k downloads (slopsquatting), publisher drift, and non-existent hallucinated names.
38
+ - **Cross-Platform Compatibility:** Fully tested and natively supported across macOS, Linux, and Windows.
39
+ - **Fails Open:** Designed so that if it crashes or can't reach the registry, it fails open. It will never permanently wedge your terminal or block your work.
40
+
41
+ ---
42
+
43
+ ## 🚀 Installation
44
+
45
+ Install it as a dev-dependency in your repository:
14
46
 
15
47
  ```sh
16
- npm install --save-dev agentinel && npx asen init
48
+ npm install --save-dev agentinel
49
+ npx asen init
17
50
  ```
51
+ *(No account, no server, no complex configuration.)*
18
52
 
19
- That sets up a hook for whichever coding agents you use, plus a git pre-commit hook. No account, no
20
- server, no configuration.
53
+ ---
21
54
 
22
- You can also try it with `npx agentinel init` and nothing installed, though the agent hook then
23
- resolves through npx on every command, which is slower.
55
+ ## 🤖 1. Agentic Use (Native Hooks)
24
56
 
25
- ## What it checks
57
+ Agentinel wires itself directly into the native pre-execution hooks of popular CLI agents: **Claude Code, Codex CLI, Copilot CLI, and Gemini CLI**.
26
58
 
27
- Every package an install would actually bring in, not just the one you named. `npm install express`
28
- looks like one package and installs 67, and most real npm malware hides in the transitive ones.
59
+ When an agent attempts to run `npm install`, Agentinel intercepts the event (e.g., `PreToolUse` for Claude) and scans the requested dependency tree.
29
60
 
30
- - **Known malware.** A bundled list of 216,000 packages confirmed malicious (from the open OSV
31
- database), matched on your machine. Nothing about what you install is ever sent anywhere.
32
- - **npm takedowns.** Packages npm itself has pulled for security.
33
- - **New and unused.** Registered in the last 30 days with under 1,000 monthly downloads, the classic
34
- slopsquat shape.
35
- - **No track record.** No repository, one version ever, barely downloaded.
36
- - **Sudden bloat.** A patch release that triples the amount of code, paired with a change of
37
- publisher: the fingerprint of a hijacked maintainer account.
61
+ ### How it feeds back to the AI
62
+ If Agentinel flags a package, it feeds the context *back* to the AI agent in a concise format the agent understands, rather than just crashing the terminal.
38
63
 
39
- Names that do not exist on npm at all are called out too, since a name an agent invented is exactly
40
- what a slopsquatter waits to register.
64
+ **Example Intercept:**
65
+ ```json
66
+ {
67
+ "hookEvent": "PreToolUse",
68
+ "action": "BLOCK",
69
+ "reason": "agentinel blocked 'react-router-v7-beta': Package does not exist on npm (hallucination)."
70
+ }
71
+ ```
72
+ The AI reads this, realizes the package is fake or malicious, and intelligently searches for the correct alternative instead of blindly retrying.
73
+
74
+ ---
41
75
 
42
- Against the 100 most depended-on packages on npm it flags **zero** of them, while catching every
43
- package in its known-bad test set. A security tool that cries wolf gets uninstalled the same day, so
44
- that number is the one that matters.
76
+ ## 🧑‍💻 2. Normal / Human Use (The Shim)
45
77
 
46
- ## Which agents
78
+ What about installs that never go through an agent? (e.g., You typing `npm install` manually).
47
79
 
48
- CLI agents, all through their native pre-execution hook: **Claude Code, Codex CLI, Copilot CLI, and
49
- Gemini CLI**. `asen init` wires up whichever of them it finds on your machine. When it blocks
50
- something in strict mode, the agent is told why in a way it understands, so it looks for a safe
51
- alternative instead of retrying.
80
+ Agentinel provides an opt-in **PATH shim**.
52
81
 
53
- For installs that never go through an agent, a person typing `npm i` by hand or a script shelling
54
- out, there is an opt-in shim (`asen init --shim`) that checks those too. And the git pre-commit hook
55
- scans the staged lockfile, so a poisoned dependency cannot slip in through a commit either.
82
+ ```sh
83
+ npx asen init --shim
84
+ ```
56
85
 
57
- ## Warn or block
86
+ This puts a tiny, fail-open wrapper script earlier in your `PATH`. When you type `npm install`, the shim checks the package first. If it's safe, the real `npm` command runs instantly.
58
87
 
59
- Warn is the default: it tells you and the agent, and gets out of the way. Set `"mode": "strict"` in
60
- `.agentinel.json` to turn a finding into a block.
88
+ **Terminal Example:**
89
+ ```bash
90
+ $ npm install left-pad-malicious
61
91
 
62
- ## Commands
92
+ ⚠️ agentinel warning: left-pad-malicious is 2 days old and has 12 downloads.
93
+ This matches the profile of a slopsquatting or malicious package.
94
+ ```
63
95
 
64
- ```sh
65
- npx asen init # set up hooks in this repo
66
- npx asen init --shim # also guard installs you type by hand
67
- asen check # check the staged dependencies now
68
- asen check some-package # check a specific package
69
- asen allow <pkg> --reason "why" # allowlist a package, with a logged reason
70
- asen unshim # remove the shim
96
+ ---
97
+
98
+ ## 🔒 3. The Git Pre-Commit Hook
99
+
100
+ As a final safety net, `asen init` installs a Git pre-commit hook.
101
+ Before you can commit a change to `package-lock.json`, Agentinel scans the staged lockfile. If a poisoned dependency slipped in somehow, the commit is flagged, ensuring malware never reaches your `main` branch.
102
+
103
+ ---
104
+
105
+ ## ⚖️ Competitors vs. Us
106
+
107
+ How do we stack up against traditional commercial security scanners?
108
+
109
+ | Feature | Agentinel (Us) | Commercial Alternatives |
110
+ |---|---|---|
111
+ | **Cost Model** | **100% Free / Zero-cost** | Monthly Subscriptions |
112
+ | **Data Privacy** | **100% Local (No cloud)** | Sends telemetry/code to cloud |
113
+ | **Agent Hooking** | **Native (intercepts AI directly)** | Scans terminal post-facto |
114
+ | **Feedback Loop** | **Tells AI *why* it failed** | Just blocks the terminal |
115
+ | **Setup** | **Zero-config, drop-in** | Requires API keys & accounts |
116
+ | **Malware Database** | Local OSV Feed (~216k pkgs) | Proprietary Feeds |
117
+ | **Feed Freshness** | *Lags 1-3 days behind OSV* | Real-time / Minutes |
118
+ | **Detection Method** | *Version-exact + Heuristics* | Advanced Behavioral Analysis |
119
+
120
+ *Note: We currently lag slightly on feed freshness (by a few days) and advanced behavioral analysis compared to paid enterprise tools. These are areas we acknowledge and plan to explore and improve in future versions, without compromising our zero-cost, 100% local philosophy.*
121
+
122
+ ---
123
+
124
+ ## ⚙️ Modes: warn vs strict
125
+
126
+ Agentinel supports two operating modes, controlled by the `mode` field. You can switch between them using `npx asen mode <warn|strict>`.
127
+
128
+ ### warn (default)
129
+ Agentinel surfaces a warning in the agent output but does not block the install. The agent decides whether to proceed.
130
+
131
+ `.agentinel.json`
132
+ ```json
133
+ {
134
+ "mode": "warn"
135
+ }
136
+ ```
137
+ *Best for teams migrating to Agentinel gradually or using agents in read-heavy workflows.*
138
+
139
+ ### strict
140
+ Agentinel hard-blocks the install and returns an error payload to the agent. The install never reaches npm.
141
+
142
+ `.agentinel.json`
143
+ ```json
144
+ {
145
+ "mode": "strict"
146
+ }
147
+ ```
148
+ *Recommended for production repos, CI pipelines, and any project with autonomous agentic access.*
149
+
150
+ ---
151
+
152
+ ## 🧰 Command Reference
153
+
154
+ Here are all the commands you can run via `npx asen <command>`:
155
+
156
+ ### `npx asen init [--shim]`
157
+ Wires up agent hooks and git hooks in the current repo.
158
+ ```bash
159
+ $ npx asen init
160
+ wrote .agentinel.json
161
+ registered the Claude Code PreToolUse hook in .claude/settings.json
162
+ installed the git pre-commit hook in .git/hooks
163
+
164
+ agentinel is set up. New npm packages will be checked before they land.
165
+ Default mode is warn. Set "mode": "strict" in .agentinel.json to block instead.
71
166
  ```
72
167
 
73
- `asen check` exits non-zero when something is flagged, so it works as a CI step.
168
+ When used with `--shim`, it wires up hooks AND installs the global PATH shim for human terminal protection.
169
+ ```bash
170
+ $ npx asen init --shim
171
+ wrote .agentinel.json
172
+ registered the Claude Code PreToolUse hook in .claude/settings.json
173
+ installed the git pre-commit hook in .git/hooks
174
+ wrote shims for npm, npx, pnpm, yarn, bun in /Users/user/.agentinel/bin
175
+ added the shims to PATH in /Users/user/.zshrc
176
+ Mode is warn, so a risky package typed at the terminal will be reported, not blocked.
177
+ Open a new terminal, or run \`asen unshim\` to undo this.
178
+
179
+ agentinel is set up. New npm packages will be checked before they land.
180
+ Default mode is warn. Set "mode": "strict" in .agentinel.json to block instead.
181
+ ```
74
182
 
75
- The allowlist lives in `.agentinel.json` and is committed, so the reason a package was trusted is
76
- visible to everyone on the repo. It is a trail, not a silent bypass.
183
+ ### `npx asen check [pkg...]`
184
+ Scans the currently staged dependencies in your lockfile. Exits non-zero if flagged (great for CI/CD pipelines).
185
+ ```bash
186
+ $ npx asen check
187
+ checked 142 package(s), nothing suspicious
188
+ ```
77
189
 
78
- ## How it stays out of your way
190
+ Scans a specific package instantly without installing it.
191
+ ```bash
192
+ $ npx asen check react-router-v7-fake
193
+ ⚠️ agentinel warning: react-router-v7-fake is 1 day old and has 4 downloads.
194
+ This matches the profile of a slopsquatting or malicious package.
195
+ ```
79
196
 
80
- agentinel does no network interception. It runs no proxy, changes no TLS settings, and injects no
81
- environment variables. So it cannot break `npm test`, a private registry, or a Rust or Go build, the
82
- way a man-in-the-middle proxy can. The malware list is matched locally and works offline. If the npm
83
- API is unreachable, a check is skipped with a note rather than blocking your work.
197
+ ### `npx asen allow <pkg> --reason "..."`
198
+ Adds a package to the allowlist in `.agentinel.json` with a required reason. This provides an audited trail for your team.
199
+ ```bash
200
+ $ npx asen allow my-internal-pkg --reason "Internal company package not on public npm"
201
+ allowlisted my-internal-pkg in .agentinel.json
202
+ ```
84
203
 
85
- ## Platforms
204
+ ### `npx asen mode <warn|strict>`
205
+ Switches Agentinel's operating mode in the `.agentinel.json` file.
206
+ ```bash
207
+ $ npx asen mode strict
208
+ set mode to strict in .agentinel.json
209
+ ```
86
210
 
87
- macOS and Linux are fully supported. Windows works too: the agent hooks and the git pre-commit hook
88
- run, and the optional shim installs as a PowerShell-friendly wrapper. Windows is written and covered
89
- by tests but has had less real-world use than macOS and Linux, so if something misbehaves there,
90
- please open an issue.
211
+ ### `npx asen unshim`
212
+ Removes the global PATH shim.
213
+ ```bash
214
+ $ npx asen unshim
215
+ removed /Users/user/.agentinel/bin
216
+ removed the PATH line from /Users/user/.zshrc
217
+ ```
91
218
 
92
- ## Scope
219
+ ---
93
220
 
94
- The npm registry only, which covers npm, pnpm, yarn, and bun, since they all install from it. Not a
95
- CVE scanner, that is what `npm audit`, Snyk, and Dependabot are for. This finds malicious packages,
96
- not vulnerable-but-legitimate ones.
221
+ ## 🤝 Contributing & Maintainers
97
222
 
98
- ## Contributing
223
+ We welcome contributions!
224
+ - Please read our [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, the zero-cost architecture rules, and the process for submitting pull requests.
99
225
 
100
- See [CONTRIBUTING.md](CONTRIBUTING.md).
226
+ **Maintainer:** [Aman Janwani](https://github.com/aman-janwani)
101
227
 
102
- ## License
228
+ ## 📄 License
103
229
 
104
- MIT. See [LICENSE](LICENSE).
230
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
package/dist/asen.js CHANGED
@@ -102,7 +102,21 @@ import { join } from "path";
102
102
  // src/config/schema.ts
103
103
  var CONFIG_FILENAME = ".agentinel.json";
104
104
  function defaultConfig() {
105
- return { mode: "warn", allow: [] };
105
+ return {
106
+ mode: "warn",
107
+ allow: [
108
+ {
109
+ name: "asen",
110
+ reason: "Agentinel CLI tool",
111
+ date: (/* @__PURE__ */ new Date()).toISOString().substring(0, 10)
112
+ },
113
+ {
114
+ name: "agentinel",
115
+ reason: "Agentinel package",
116
+ date: (/* @__PURE__ */ new Date()).toISOString().substring(0, 10)
117
+ }
118
+ ]
119
+ };
106
120
  }
107
121
  function parseConfig(raw, warn2 = () => {
108
122
  }) {
@@ -1464,6 +1478,24 @@ function asRecord2(value) {
1464
1478
  return typeof value === "object" && value !== null ? value : null;
1465
1479
  }
1466
1480
 
1481
+ // src/commands/mode.ts
1482
+ function runMode(targetMode) {
1483
+ if (targetMode !== "warn" && targetMode !== "strict") {
1484
+ console.error("usage: asen mode <warn|strict>");
1485
+ return 1;
1486
+ }
1487
+ const repoRoot = repoRootOrCwd();
1488
+ const config = loadConfig(repoRoot);
1489
+ if (config.mode === targetMode) {
1490
+ console.log(`mode is already ${targetMode}`);
1491
+ return 0;
1492
+ }
1493
+ config.mode = targetMode;
1494
+ saveConfig(repoRoot, config);
1495
+ console.log(`set mode to ${targetMode} in .agentinel.json`);
1496
+ return 0;
1497
+ }
1498
+
1467
1499
  // src/hooks/claude-code.ts
1468
1500
  import { existsSync as existsSync6 } from "fs";
1469
1501
  import { join as join6 } from "path";
@@ -1769,6 +1801,7 @@ var USAGE = `asen, a guard for AI coding agent workflows
1769
1801
  asen init [--shim] set up the hooks and config in this repo
1770
1802
  asen check [pkg...] check staged dependencies, or specific packages
1771
1803
  asen allow <pkg> --reason "..." allowlist a flagged package, with a logged reason
1804
+ asen mode <warn|strict> switch Agentinel's operating mode
1772
1805
  asen unshim remove the PATH shims that --shim installed
1773
1806
  `;
1774
1807
  async function main(argv2) {
@@ -1780,6 +1813,8 @@ async function main(argv2) {
1780
1813
  return runCheck(positionals(rest));
1781
1814
  case "allow":
1782
1815
  return runAllow(positionals(rest)[0], readFlag(rest, "--reason"));
1816
+ case "mode":
1817
+ return runMode(positionals(rest)[0]);
1783
1818
  case "unshim":
1784
1819
  return removeShim();
1785
1820
  // Not documented in the usage text on purpose. These are what the installed hooks call.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentinel",
3
- "version": "0.0.1",
3
+ "version": "1.0.0",
4
4
  "description": "Catches AI hallucinated npm packages before an agent installs them",
5
5
  "license": "MIT",
6
6
  "author": "Aman Janwani",