@ev-ai/agent-hook 1.1.7 → 1.2.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.
- package/COLLECTED-DATA.md +1 -1
- package/README.md +18 -3
- package/dist/cli.mjs +38 -36
- package/dist/hook.mjs +32 -30
- package/dist/launcher-update.mjs +5 -0
- package/dist/launcher.mjs +5 -0
- package/dist/managed-hooks-snippet.cjs +177 -0
- package/dist/managed-hooks-snippet.d.ts +3 -0
- package/dist/managed-hooks-snippet.mjs +149 -0
- package/dist/plugin-hooks.mjs +36 -25
- package/package.json +15 -2
package/COLLECTED-DATA.md
CHANGED
|
@@ -10,7 +10,7 @@ What `@ev-ai/agent-hook` POSTs to the ev-ai collector (`POST /{orgToken}/hook`,
|
|
|
10
10
|
| `session_end` | Session stops |
|
|
11
11
|
| `tool_invoked` | Tool, skill, MCP, shell, or file-edit hook fires |
|
|
12
12
|
|
|
13
|
-
Every event also carries: UTC timestamp, `installation_id` (per-machine under `~/.ev-ai/agent-hook/installation.json`; on ephemeral CI/cloud homes derived from platform seeds such as `GITHUB_REPOSITORY_ID`+`GITHUB_ACTOR` / `CODESPACE_NAME` / Cursor Cloud `CURSOR_PROJECT_DIR`+`CURSOR_USER_EMAIL` / Claude Code remote origin remote + git author email, or pinned via `EV_AI_HOOK_INSTALLATION_ID`), runner `platform` (`claude` / `cursor` / `codex`), `platform_agent_id` (Layer-1 inventory join key: `{owner}/{repo}:{scopePath/}{markerDir}`, e.g. `acme/my-app:.claude` or `acme/my-app:apps/web/.cursor`), `session_id`, `turn_id`, raw `runner_event` name, `agent_hook_version`, `host_arch`, `node_version`, `build_ms` (wall-clock milliseconds to assemble the envelope before the collector POST; not tool/session duration), and `self_config.operator` (human identity — see Operator identity below; skipped when `EV_AI_HOOK_USER_SPEC=off`).
|
|
13
|
+
Every event also carries: UTC timestamp, `installation_id` (per-machine under `~/.ev-ai/agent-hook/installation.json`; on ephemeral CI/cloud homes derived from platform seeds such as `GITHUB_REPOSITORY_ID`+`GITHUB_ACTOR` / `CODESPACE_NAME` / Cursor Cloud `CURSOR_PROJECT_DIR`+`CURSOR_USER_EMAIL` / Claude Code remote origin remote + git author email, or pinned via `EV_AI_HOOK_INSTALLATION_ID`), runner `platform` (`claude` / `cursor` / `codex`), `platform_agent_id` (Layer-1 inventory join key: `{owner}/{repo}:{scopePath/}{markerDir}`, e.g. `acme/my-app:.claude` or `acme/my-app:apps/web/.cursor`), `session_id`, `turn_id`, raw `runner_event` name, `agent_hook_version`, `host_arch`, `node_version`, `build_ms` (wall-clock milliseconds to assemble the envelope before the collector POST; not tool/session duration), and `self_config.operator` (human identity — see Operator identity below; skipped when `EV_AI_HOOK_USER_SPEC=off`). When the process was started by the npx launcher (`dist/launcher.mjs`), the envelope also includes `launcher_version`, `hook_source` (`bundled` / `cached` / `bootstrap`), `hook_fallback_reason` (string or `null`), and `launcher_scope_match` (whether the hook's POST URL hashes to the same collector scope the launcher resolved). Direct `node dist/hook.mjs`, the compiled binary, and the marketplace plugin launcher omit those four fields. On `session_start` only, a launcher-started hook also adds `launcher_scope` (the opaque collector-scope hash from `EV_AI_LAUNCHER_SCOPE`, never a token) and `launcher_attempt` (`n`, `latest_claim`, `outcome`, `finished_at`, `selection_version`). `outcome` is a `.done` result (`updated`, `current`, `repaired`, `bundled`, `skipped:below_floor`, `skipped:quarantined`, `failed:*`, …) or `incomplete` when the latest claim has no `.done` past its owner budget. A log read error omits `launcher_attempt` and never delays the runner ack. Other events carry only the four launcher fields above.
|
|
14
14
|
|
|
15
15
|
## Tracked data points
|
|
16
16
|
|
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ This is an **opt-in, first-party observability agent** that an ev-ai customer in
|
|
|
13
13
|
|
|
14
14
|
## Install
|
|
15
15
|
|
|
16
|
-
**Primary path:** enable the ev-ai **runner plugins** (Claude / Cursor / Codex) from the hosted marketplace. Their hooks
|
|
16
|
+
**Primary path:** enable the ev-ai **runner plugins** (Claude / Cursor / Codex) from the hosted marketplace. Their hooks run the shipped `hook.mjs` with Node (no package version in the command). Your repo commits only a shared `collector_url` manifest plus plugin enablement — not per-event blocks in `.claude/settings.json` / `.cursor/hooks.json` / `.codex/hooks.json`.
|
|
17
17
|
|
|
18
18
|
**Fallback:** the `install` CLI merges hooks into those three config files directly.
|
|
19
19
|
|
|
@@ -31,7 +31,7 @@ npx @ev-ai/agent-hook@X.Y.Z configure \
|
|
|
31
31
|
2. Enable the Claude / Cursor / Codex plugins from the hosted marketplace.
|
|
32
32
|
3. Commit the shared manifest (`.claude/ev-ai-runtime-report.json`) plus plugin enablement **or** the file-wired hook configs (not both for the same events). Restart runners.
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
File-wiring pins an exact package version, never `@latest`. Plugin runtime bumps ride the shipped `hook.mjs` payload.
|
|
35
35
|
|
|
36
36
|
**Migrating from file-wiring:** strip ev-ai per-event blocks while keeping the manifest:
|
|
37
37
|
|
|
@@ -132,6 +132,21 @@ Each developer's `installation_id` is created on first hook fire and stored once
|
|
|
132
132
|
|
|
133
133
|
Per-event execution uses `npx` (primary) or the pinned binary (CDN path). The runner-facing process **acks immediately** (`{"continue":true}` + exit 0) after draining stdin and spawning a detached `__work` child that collects + POSTs — **except teardown events**, which stay in-process and await the HTTP POST so a runner that tears down the process tree on exit cannot kill the worker mid-flight. Teardown = Claude `SessionEnd` / `StopFailure`, Codex `Stop` (its only end signal), and `SubagentStop`. Per-turn Claude `Stop` / Cursor `stop` fire at the end of **every turn** (not teardown), so they detach like tool events and never block the runner between turns. Set `EV_AI_HOOK_SYNC=1` to keep all events in-process for debugging.
|
|
134
134
|
|
|
135
|
+
### Hook updates (npx path)
|
|
136
|
+
|
|
137
|
+
The npx package's entry point is a small launcher. It runs the hook your collector selects, from a per-machine cache under `~/.ev-ai/agent-hook/js/`, and otherwise the hook bundled in the pinned package. A cached hook is re-verified (sha256) on every event, and any problem with it (missing, altered, incompatible with this Node or launcher, or failing to start twice in a row) falls back to the bundled hook for that event.
|
|
138
|
+
|
|
139
|
+
**Network.** Besides the collector POST, the launcher makes two kinds of request, both only on the npx path:
|
|
140
|
+
|
|
141
|
+
- `GET /{orgToken}/version` on the same collector, at most once per 6 h per collector: on the first event in a new collector scope, then from a detached background refresh at session start. No request is made on other events.
|
|
142
|
+
- When the collector names a release, a download of that release's npm tarball from `https://registry.npmjs.org/@ev-ai/agent-hook/-/`. The tarball is checked against the sha512 integrity the collector sent before it is unpacked, and only `package.json` and `dist/hook.mjs` are extracted. No other destination is contacted.
|
|
143
|
+
|
|
144
|
+
**Kill switch.** `EV_AI_AUTO_UPDATE=0`, or `"auto_update": false` in `~/.ev-ai/config.json`, always runs the bundled hook and makes neither request. Ephemeral CI homes start cold on every run, so their first event makes the `/version` check (within a 3 s budget); set `EV_AI_AUTO_UPDATE=0` in CI if you want the pinned hook with no extra request.
|
|
145
|
+
|
|
146
|
+
**Status.** `npx @ev-ai/agent-hook@X.Y.Z status` prints which hook runs for the current repo's collector and why, when the next check may happen, and the last check's result. `--all` adds every other collector scope on the machine, and `--json` prints the same fields as JSON. `status` never makes a request.
|
|
147
|
+
|
|
148
|
+
**Cache.** Deleting `~/.ev-ai/agent-hook/js/` is safe at any time: the next event runs the bundled hook and checks again.
|
|
149
|
+
|
|
135
150
|
### Gitignore (recommended)
|
|
136
151
|
|
|
137
152
|
```gitignore
|
|
@@ -188,4 +203,4 @@ Or:
|
|
|
188
203
|
curl -fsSL https://cdn.ev-ai.ai/agent-hook/install.sh | sh -s -- uninstall
|
|
189
204
|
```
|
|
190
205
|
|
|
191
|
-
`uninstall` removes ev-ai-owned hook entries from Claude/Cursor/Codex config files (leaves other hooks intact) and deletes `ev-ai-runtime-report.json` manifest(s) in the current git repo. Does not remove `~/.ev-ai/agent-hook/` (pinned binary
|
|
206
|
+
`uninstall` removes ev-ai-owned hook entries from Claude/Cursor/Codex config files (leaves other hooks intact) and deletes `ev-ai-runtime-report.json` manifest(s) in the current git repo. Does not remove `~/.ev-ai/agent-hook/` (pinned binary, per-machine identity, and the npx hook cache under `~/.ev-ai/agent-hook/js/`).
|