@ev-ai/agent-hook 1.0.7 → 1.0.8
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 +13 -12
- package/README.md +4 -2
- package/dist/cli.mjs +25 -20
- package/dist/hook.mjs +21 -15
- package/dist/plugin-hooks.mjs +6 -1
- package/package.json +1 -1
package/COLLECTED-DATA.md
CHANGED
|
@@ -10,19 +10,19 @@ 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
|
|
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`, and `build_ms` (wall-clock milliseconds to assemble the envelope before the collector POST; not tool/session duration).
|
|
14
14
|
|
|
15
15
|
## Tracked data points
|
|
16
16
|
|
|
17
17
|
### On `session_start`
|
|
18
18
|
|
|
19
|
-
- **Host** — hostname, OS / version, username, shell, TTY, runtime context (`interactive` / `github_actions` / `claude_remote` / `cursor_cloud` / `codespaces` / `managed` / `container` / `
|
|
19
|
+
- **Host** — hostname, OS / version, username, shell, TTY, runtime context (`interactive` / `github_actions` / `claude_remote` / `cursor_cloud` / `codespaces` / `gitlab_ci` / `managed` / `container` / `unknown`). Cloud / CI contexts require positive evidence (`GITHUB_ACTIONS`, `CLAUDE_CODE_REMOTE`, `CODESPACES`, `GITLAB_CI`, managed CI platform markers, truthy `CI`, or Cursor Cloud). Cursor Cloud is `CURSOR_AGENT` without a local IDE host, a `bc-` background-composer session id on Linux, or hostname `cursor` + os user `ubuntu` + `CURSOR_VERSION` on Linux. `CURSOR_AGENT` / those extra markers are not enough when a local Cursor / VS Code extension host is present (desktop agent shells set `CURSOR_AGENT` too). `CURSOR_CODE_REMOTE` alone is not Cursor Cloud (Remote-SSH boxes also set it). `gitlab_ci` is `GITLAB_CI`. `managed` covers generic `CI=true` plus named platforms that often omit it (`TF_BUILD`, `JENKINS_URL`, `BUILDKITE`, `CIRCLECI`, `CODEBUILD_BUILD_ID`, `DRONE`, …). `container` covers `/.dockerenv`, k8s (`KUBERNETES_SERVICE_HOST`), and VS Code / Codespaces-style remote containers (`REMOTE_CONTAINERS` / `DEVCONTAINER`). `interactive` covers TTY / `TERM` / `TERM_PROGRAM`, SSH session markers, macOS GUI launch (`__CFBundleIdentifier`, `XPC_SERVICE_NAME`), IDE host markers (`VSCODE_PID`, …), and Linux / Windows desktop session vars. Residual with no positive cloud or local evidence is `unknown` (the former `cron` catch-all for “no TTY” was removed — GUI-launched agents often have no TTY). Optional virt and cloud provider / region / instance id. Cloud metadata is probed only for non-interactive contexts; interactive laptop sessions skip IMDS entirely. Non-interactive probes are cached locally for 24h per context.
|
|
20
20
|
- **Git** — origin remote (credentials stripped), branch, HEAD SHA, dirty flag
|
|
21
|
-
- **Env (allowlist only)** — CI markers (`CI`, `GITHUB_*`, `GITLAB_CI`, `CIRCLECI`, `BUILDKITE`, `TF_BUILD`, …), actor identity markers (`GITHUB_ACTOR`, `GITLAB_USER_*`, `BUILD_REQUESTEDFOR*`, `BUILDKITE_BUILD_CREATOR*`, `BUILD_USER*`, `CHANGE_AUTHOR*`, `CIRCLE_USERNAME`, `CODEBUILD_INITIATOR`, `DRONE_COMMIT_AUTHOR*`, `EV_AI_HOOK_OPERATOR_*`, `GIT_AUTHOR_*`, `GIT_COMMITTER_*`, `EMAIL`, …), cloud session markers (`CLAUDE_CODE_REMOTE`, `CURSOR_AGENT`, `CODESPACES`), `NODE_ENV`, `TERM_PROGRAM`, vendor base-URL overrides (`ANTHROPIC_BASE_URL`, `OPENAI_BASE_URL`, …), Claude Bedrock/Vertex flags. API keys and proxy vars are never read. Gateway URLs have embedded credentials and credential-shaped query params (`key`, `api-key`, `token`, `sig`, …) redacted.
|
|
21
|
+
- **Env (allowlist only)** — CI markers (`CI`, `GITHUB_*`, `GITLAB_CI`, `CIRCLECI`, `BUILDKITE`, `TF_BUILD`, …), actor identity markers (`GITHUB_ACTOR`, `GITLAB_USER_*`, `BUILD_REQUESTEDFOR*`, `BUILDKITE_BUILD_CREATOR*`, `BUILD_USER*`, `CHANGE_AUTHOR*`, `CIRCLE_USERNAME`, `CODEBUILD_INITIATOR`, `DRONE_COMMIT_AUTHOR*`, `EV_AI_HOOK_OPERATOR_*`, `GIT_AUTHOR_*`, `GIT_COMMITTER_*`, `EMAIL`, …), cloud session markers (`CLAUDE_CODE_REMOTE`, `CURSOR_AGENT`, `CURSOR_VERSION`, `CURSOR_USER_EMAIL`, `CODESPACES`), `CURSOR_PROJECT_DIR` (present/absent only — the path is not shipped), `NODE_ENV`, `TERM_PROGRAM`, vendor base-URL overrides (`ANTHROPIC_BASE_URL`, `OPENAI_BASE_URL`, …), Claude Bedrock/Vertex flags. API keys and proxy vars are never read. Gateway URLs have embedded credentials and credential-shaped query params (`key`, `api-key`, `token`, `sig`, …) redacted.
|
|
22
22
|
- **MCP inventory** — declared server **names** (and discovery source), not commands/URLs/env
|
|
23
23
|
- **User-scope config** — `cli_version` (claude / agent|cursor-agent / codex `--version`); model (Claude; SessionStart stdin `model` preferred over settings-file), Claude-only `claude_version` mirror; presence/size of global settings / memory / MCP files; name+size listings of global skills, commands, subagents, rules (full listing when the hash changed or every 10th session start as a repair re-send; capped at 500 entries per list with `truncated: true` when capped). File **contents** are not sent.
|
|
24
|
-
- **User spec (home-dir components)** — per-component delta of skills / commands / rules / memory / subagents / hooks / MCP servers / plugins from `~/.claude`, `~/.cursor`, `~/.codex`, `~/.agents`. Walked on the **first** `session_start` for a runner and again only after a **14-hour cooldown** (`user_spec_collected_at_ms` in `self-config-cache.json`); mid-cooldown session starts skip the home walk and omit `user_spec*` / `operator`. Each upsert row carries `kind`, path-derived `name`, home-relative `path`, capped file `text` (≤20_000 chars) for file-backed kinds, `content_hash`, `origin` (`user` or `plugin:<name>@<marketplace>`), `enabled`, optional `trigger` / `attributes`. Frontmatter fields (`name`, `description`, …) are not parsed on the client — the collector derives them from `text`. Only **changed or new** components are sent (`user_spec`); removals are explicit tombstones (`user_spec_removed: [{ path, name }]`). Unchanged scope after a cooldown refresh → hash/count/truncated scalars alone. First walk is a full authoritative snapshot (`user_spec_full: true`). File `text` is shipped **once per `content_hash`** (later sends omit the body when that hash was already delivered); under the ~300 KiB user-spec byte budget, overflowing bodies are deferred (`user_spec_text_deferred`) before rows are dropped. Self-config / operator caches commit only after a successful collector POST. Hook rows send `action_kind` + `action_hash` only — never the command string. MCP rows send name + transport only. Plugin rows never include `installPath` / `projectPath`. Disabled with `EV_AI_HOOK_USER_SPEC=off`.
|
|
25
|
-
- **Operator identity** — on the first user-spec collect for an installation (and again when the 14-hour user-spec cooldown elapses): `git_user_name` / `git_user_email` from `git config` when set (`identity_source: "git_config"`). When unset, tries `GIT_AUTHOR_NAME`/`GIT_AUTHOR_EMAIL`, then `GIT_COMMITTER_*`, then `EMAIL` (`identity_source: "git_env"`). Bot-shaped git identity (`*[bot]*`, `action@github.com`, `noreply@anthropic.com`, `cursoragent@cursor.com`, …) is skipped so CI/cloud actor env vars can win: explicit `EV_AI_HOOK_OPERATOR_NAME` / `EV_AI_HOOK_OPERATOR_EMAIL` → `identity_source: "configured"`; then `GITHUB_ACTOR` / `GITHUB_TRIGGERING_ACTOR` / `GITHUB_USER` → `"github"`; `GITLAB_USER_*` → `"gitlab"`; Azure DevOps `BUILD_REQUESTEDFOR*` → `"azure_devops"`; Buildkite `BUILDKITE_BUILD_CREATOR*` → `"buildkite"`; Jenkins `BUILD_USER*` / `CHANGE_AUTHOR*` → `"jenkins"`; CircleCI `CIRCLE_USERNAME` → `"circleci"`; CodeBuild `CODEBUILD_INITIATOR` → `"codebuild"`; Drone/Woodpecker `DRONE_COMMIT_AUTHOR*` → `"drone"`. When those are also absent, falls back to the HEAD commit author from `git log -1` (`identity_source: "git_log"`). Claude Code remote (`CLAUDE_CODE_REMOTE`) and Cursor cloud (`CURSOR_AGENT`) without a git or CI actor are tagged `identity_source: "cloud"`
|
|
24
|
+
- **User spec (home-dir components)** — per-component delta of skills / commands / rules / memory / subagents / hooks / MCP servers / plugins from `~/.claude`, `~/.cursor`, `~/.codex`, `~/.agents`. Project spec in the working directory is not part of this snapshot (in-repo files go through the git inventory pipeline; non-git cwd is recorded only as `hook_input.cwd`). Walked on the **first** `session_start` for a runner and again only after a **14-hour cooldown** (`user_spec_collected_at_ms` in `self-config-cache.json`); mid-cooldown session starts skip the home walk and omit `user_spec*` / `operator`. Each upsert row carries `kind`, path-derived `name`, home-relative `path`, capped file `text` (≤20_000 chars) for file-backed kinds, `content_hash`, `origin` (`user` or `plugin:<name>@<marketplace>`), `enabled`, optional `trigger` / `attributes`. Frontmatter fields (`name`, `description`, …) are not parsed on the client — the collector derives them from `text`. Only **changed or new** components are sent (`user_spec`); removals are explicit tombstones (`user_spec_removed: [{ path, name }]`). Unchanged scope after a cooldown refresh → hash/count/truncated scalars alone. First walk is a full authoritative snapshot (`user_spec_full: true`). File `text` is shipped **once per `content_hash`** (later sends omit the body when that hash was already delivered); under the ~300 KiB user-spec byte budget, overflowing bodies are deferred (`user_spec_text_deferred`) before rows are dropped. Self-config / operator caches commit only after a successful collector POST. Hook rows send `action_kind` + `action_hash` only — never the command string. MCP rows send name + transport only. Plugin rows never include `installPath` / `projectPath`. Disabled with `EV_AI_HOOK_USER_SPEC=off`.
|
|
25
|
+
- **Operator identity** — on the first user-spec collect for an installation (and again when the 14-hour user-spec cooldown elapses): `git_user_name` / `git_user_email` from `git config` when set (`identity_source: "git_config"`). When unset, tries `GIT_AUTHOR_NAME`/`GIT_AUTHOR_EMAIL`, then `GIT_COMMITTER_*`, then `EMAIL` (`identity_source: "git_env"`). Bot-shaped git identity (`*[bot]*`, `action@github.com`, `noreply@anthropic.com`, `cursoragent@cursor.com`, …) is skipped so CI/cloud actor env vars can win: explicit `EV_AI_HOOK_OPERATOR_NAME` / `EV_AI_HOOK_OPERATOR_EMAIL` / `EV_AI_HOOK_OPERATOR_LOGIN` → `identity_source: "configured"`; then `GITHUB_ACTOR` / `GITHUB_TRIGGERING_ACTOR` / `GITHUB_USER` → `"github"`; `GITLAB_USER_*` → `"gitlab"`; Azure DevOps `BUILD_REQUESTEDFOR*` → `"azure_devops"`; Buildkite `BUILDKITE_BUILD_CREATOR*` → `"buildkite"`; Jenkins `BUILD_USER*` / `CHANGE_AUTHOR*` → `"jenkins"`; CircleCI `CIRCLE_USERNAME` → `"circleci"`; CodeBuild `CODEBUILD_INITIATOR` → `"codebuild"`; Drone/Woodpecker `DRONE_COMMIT_AUTHOR*` → `"drone"`. When those are also absent, falls back to the HEAD commit author from `git log -1` (`identity_source: "git_log"`). Claude Code remote (`CLAUDE_CODE_REMOTE`) and Cursor cloud (`CURSOR_AGENT`) without a git or CI actor are tagged `identity_source: "cloud"`; Cursor cloud sets `git_user_email` from `CURSOR_USER_EMAIL` when it is not the image-baked bot address (never a session uuid). CI/cloud actor sources also set `platform_login` (GitHub/GitLab/CircleCI/CodeBuild/Jenkins `BUILD_USER_ID`/Drone login, Azure DevOps `BUILD_REQUESTEDFORID`, Buildkite creator email, or `EV_AI_HOOK_OPERATOR_LOGIN`) so the collector can join installations to members without inventing a noreply email. Omitted while user-spec is on cooldown and in steady state when unchanged. Never invents an OS username. Disabled with the same `EV_AI_HOOK_USER_SPEC=off` opt-out.
|
|
26
26
|
- **Cloud identity bootstrap** — Cursor cloud agents do not fire `sessionStart`. On the first `tool_invoked` / skill event when operator identity has never been sent (any runtime context — cloud VMs with a pseudo-TTY often look `interactive`), the hook POSTs a lightweight `session_start` (`run_meta.trigger: cloud_identity_bootstrap`) with host/context/operator — no home user-spec walk, and no `cli_version` / `model` / `user_scope` / `hook_input` (those stay unset so the collector never treats bootstrap nulls as a probed empty config). Debounced in-process and across concurrent hook processes via an exclusive claim lock beside `installation.json` (`cloud-bootstrap.lock`); skipped when `EV_AI_HOOK_USER_SPEC=off`.
|
|
27
27
|
- **Permission keys (Claude)** — each rule as `{ key, mode }` where `mode` is the list it came from (`allow` / `deny` / `ask`), so a blocked rule is never mistaken for a permitted one. Absolute POSIX / Windows / `~`-anchored paths inside a rule are replaced with `<path>` (`Bash(find /Users/me/repo -name x)` → `Bash(find <path> -name x)`) — the rule shape is the posture signal, the operator's home layout is not. Capped at 200 rules, 200 characters each.
|
|
28
28
|
- **Allowlisted hook metadata** — see below (includes SessionStart `model`, `permission_mode`, …)
|
|
@@ -36,24 +36,25 @@ Every event also carries: UTC timestamp, `installation_id` (per-machine under `~
|
|
|
36
36
|
### On `tool_invoked`
|
|
37
37
|
|
|
38
38
|
- `tool_name`, `skill_name`
|
|
39
|
-
- **Cursor `skill_name` (derived, not from a native Skill tool):** slash commands via `beforeSubmitPrompt` (`/my-skill` → `tool_name: Skill`, `skill_name: my-skill`; prompt text is never POSTed); Read of `**/skills/<id>/SKILL.md` on `preToolUse` / `postToolUse` (skill id only — file path is never POSTed). Silent auto-inject with no slash and no SKILL.md Read is not observable.
|
|
39
|
+
- **Cursor `skill_name` (derived, not from a native Skill tool):** slash commands via `beforeSubmitPrompt` (`/my-skill` → `tool_name: Skill`, `skill_name: my-skill`; prompt text is never POSTed); Read of `**/skills/<id>/SKILL.md` on `preToolUse` / `postToolUse` / `beforeReadFile` (skill id only — file path is never POSTed); Shell whose command references a skill path on `beforeShellExecution` / `afterShellExecution` (id only — command string never POSTed). Silent auto-inject with no slash and no SKILL.md Read is not observable.
|
|
40
40
|
- **Claude `skill_name` (derived):** slash commands via `UserPromptExpansion` (`command_name` → `tool_name: Skill`, `skill_name: <id>`; `prompt` / `command_args` are never POSTed). Typing `/skillname` bypasses `PreToolUse(Skill)`; Read of `**/skills/<id>/SKILL.md` on Pre/Post tool hooks is also derived when present.
|
|
41
41
|
- **Codex `skill_name` (derived):** slash / custom-prompt ids via `UserPromptSubmit` (`/my-skill` → `tool_name: Skill`, `skill_name: my-skill`; prompt text is never POSTed); Bash/Shell whose `tool_input.command` references `.claude/.cursor/.agents/skills/<id>/SKILL.md` or `.codex/commands/<id>.md` (id only — command string never POSTed on allowlist); Read-like tools of those paths when present. Silent auto-inject with no slash and no skill-file touch is not observable.
|
|
42
42
|
- `tool_use_id` — opaque Claude Pre/Post join key when present in stdin
|
|
43
|
-
- `success` — `true` on Claude/Cursor `PostToolUse` / `postToolUse`, `false` on `PostToolUseFailure` / `postToolUseFailure` / Claude `PermissionDenied`, otherwise `null`
|
|
43
|
+
- `success` — `true` on Claude/Cursor `PostToolUse` / `postToolUse`, `false` on `PostToolUseFailure` / `postToolUseFailure` / Claude `PermissionDenied`, otherwise `null` (Cursor `afterFileEdit` / `afterShellExecution` have no exit code; Post* owns outcome)
|
|
44
44
|
- `failure_reason` — when `success === false`, a **failure class, never a runner message**: `interrupted` (stdin `is_interrupt`), `permission_denied` (Claude `PermissionDenied`), an identifier-shaped `failure_type` / `error_type` (`timeout`, `ShellError`), else the fixed value `error`. Runner `error` / `error_message` strings are dropped — they carry raw tool stderr including absolute paths and whole result bodies.
|
|
45
|
-
- `duration_ms` — from Claude `duration_ms` or Cursor `duration` on post-tool stdin
|
|
45
|
+
- `duration_ms` — from Claude `duration_ms` or Cursor `duration` on post-tool / `afterShellExecution` stdin
|
|
46
46
|
- `mcp_server` / `mcp_tool` — derived from opaque `tool_name` when it matches Claude `mcp__<server>__<tool>` or Cursor `MCP:<server>:<tool>` / `MCP:<tool>` (no `tool_input` parsing)
|
|
47
|
+
- `component_reference` — an opaque exact-component identifier emitted only when the hook has complete repository-backed identity evidence. Exact skill paths map to SKILL installations; exact MCP server and MCP tool invocations map to the server INTERFACE installation, never to a tool installation. Name-only, flat/unattributed MCP, malformed scope, and missing platform-agent identity stay unmatched. Absolute local paths never leave the hook process: path evidence is normalized to the repository-relative source path before hashing, and only the opaque reference is sent.
|
|
47
48
|
- `subagent_type` — on subagent start/stop hooks, which carry an agent type instead of a `tool_name`: Claude `agent_type` (`Explore`, plugin-scoped `my-plugin:reviewer`) or Cursor `subagent_type` (`generalPurpose`, `explore`). Only identifier-shaped values are sent; the neighbouring `task` / `description` / `summary` fields are free prose and are never captured
|
|
48
49
|
- Allowlisted hook metadata (see below)
|
|
49
50
|
|
|
50
51
|
### Hook metadata (default)
|
|
51
52
|
|
|
52
|
-
From runner stdin, only: session/conversation/turn ids (`prompt_id` / `prompt.id` / `generation_id` / `turn_id`), event name/source, status / `stop_reason` / SessionEnd `reason`, tool/skill name, `tool_use_id`, `permission_mode`, active `model` / Cursor `model_id`, `agent_id` / `agent_type`, Cursor `subagent_id` / `subagent_type` / `subagent_model` / `is_parallel_worker`, `effort` / `effort.level`, `duration_ms` / `duration`, failure category fields (`failure_type`, `is_interrupt` — the message fields `error`, `error_details`, `error_message` are **not** forwarded), Claude `UserPromptExpansion` metadata (`command_name`, `expansion_type`, `command_source` — never `prompt` / `command_args`), and git-root-relative `cwd_relative`
|
|
53
|
+
From runner stdin, only: session/conversation/turn ids (`prompt_id` / `prompt.id` / `generation_id` / `turn_id`), event name/source, status / `stop_reason` / SessionEnd `reason`, tool/skill name, `tool_use_id`, `permission_mode`, active `model` / Cursor `model_id`, `agent_id` / `agent_type`, Cursor `subagent_id` / `subagent_type` / `subagent_model` / `is_parallel_worker`, `effort` / `effort.level`, `duration_ms` / `duration`, Cursor shell `sandbox` (boolean), failure category fields (`failure_type`, `is_interrupt` — the message fields `error`, `error_details`, `error_message` are **not** forwarded), Claude `UserPromptExpansion` metadata (`command_name`, `expansion_type`, `command_source` — never `prompt` / `command_args`), absolute `cwd` when stdin has it, and git-root-relative `cwd_relative` in addition when the session is inside a git repo and stdin cwd is under that root. Session titles, tool args, prompts, shell commands, file paths, file contents, edits, MCP spawn commands/URLs, and tool result bodies are dropped unless the operator opts into full capture (`capture_hook_input: "full"` or `EV_AI_HOOK_CAPTURE_FULL_INPUT=1`).
|
|
53
54
|
|
|
54
|
-
Install wires Claude `SessionStart` / `UserPromptExpansion` / `PreToolUse` (all tools) / `PostToolUse` / `PostToolUseFailure` / `PermissionDenied` / `Stop` / `StopFailure` / `SessionEnd` / `SubagentStart` / `SubagentStop`; Cursor `sessionStart` / `beforeSubmitPrompt` / `preToolUse` / `postToolUse` / `postToolUseFailure` / `subagentStart` / `subagentStop` / `stop`; Codex `SessionStart` / `UserPromptSubmit` / `PreToolUse` (all tools) / `PostToolUse` / `Stop`. Re-run `install` to upgrade existing repos (Cursor
|
|
55
|
+
Install wires Claude `SessionStart` / `UserPromptExpansion` / `PreToolUse` (all tools) / `PostToolUse` / `PostToolUseFailure` / `PermissionDenied` / `Stop` / `StopFailure` / `SessionEnd` / `SubagentStart` / `SubagentStop`; Cursor `sessionStart` / `beforeSubmitPrompt` / `preToolUse` / `postToolUse` / `postToolUseFailure` / `beforeShellExecution` / `afterShellExecution` / `beforeReadFile` / `afterFileEdit` / `beforeMCPExecution` / `subagentStart` / `subagentStop` / `stop`; Codex `SessionStart` / `UserPromptSubmit` / `PreToolUse` (all tools) / `PostToolUse` / `Stop`. Re-run `install` to upgrade existing repos (Cursor-specific shell/read/edit/MCP events are added beside generic pre/post tool hooks; `runner_event` distinguishes the row).
|
|
55
56
|
|
|
56
|
-
When Cursor loads Claude (or Codex) file hooks as third-party configs alongside `.cursor/hooks.json`, the binary drops the foreign `--runner` twin so `platform` stays `cursor` and events are not duplicated. Claude Code and Codex hosts are unaffected.
|
|
57
|
+
When Cursor loads Claude (or Codex) file hooks as third-party configs alongside `.cursor/hooks.json`, the binary drops the foreign `--runner` twin so `platform` stays `cursor` and events are not duplicated. Claude Code and Codex hosts are unaffected. Stacked same-runner configs (user + project hooks, or plugin + file wiring) collapse to one POST via a short-lived claim lock (`EVENT_CLAIM_DEDUP_ENABLED=false` disables).
|
|
57
58
|
|
|
58
59
|
## PII we do not send
|
|
59
60
|
|
|
@@ -70,5 +71,5 @@ Username and hostname *are* sent (per-member usage for the installing org). The
|
|
|
70
71
|
- MCP server commands, args, env blocks, and URLs (name/transport only)
|
|
71
72
|
- Plugin `installPath` / `projectPath` (absolute / home paths)
|
|
72
73
|
- OS username as an identity substitute (git `user.name` / `user.email`, CI actor logins via `platform_login`, or CI emails are sent when available; OS username is still only present via the existing host username field)
|
|
73
|
-
- Home-directory absolute paths (rewritten to home-relative before send), local IP addresses, and listening ports
|
|
74
|
+
- Home-directory absolute paths (rewritten to home-relative before send), local IP addresses, and listening ports. Exception: the absolute working directory is always sent as `cwd` when stdin has it; `cwd_relative` is added only inside a git repo
|
|
74
75
|
- Data to any endpoint other than the org-configured collector
|
package/README.md
CHANGED
|
@@ -72,6 +72,8 @@ npx @ev-ai/agent-hook@latest install \
|
|
|
72
72
|
|
|
73
73
|
Keep Claude and Cursor both wired. Cursor also loads `.claude/settings.json` as third-party hooks; the binary suppresses those Claude/Codex-tagged twin invocations when it detects a Cursor host, so each event posts once as `platform: cursor`. Real Claude Code sessions still use the Claude hooks unchanged.
|
|
74
74
|
|
|
75
|
+
Stacked configs for the **same** runner (user-level `~/.cursor/hooks.json` plus project `.cursor/hooks.json`, or plugins enabled alongside file wiring) also fire twice. The hook collapses those to one collect + POST via a short-lived cross-process claim under `~/.ev-ai/agent-hook/claims/` (keyed by platform, session, event, turn / `tool_use_id`, and a local hash of call-identifying stdin when `tool_use_id` is absent — so distinct Cursor shell/read/edit calls in one turn are not treated as duplicates). Weak payloads without a strong id fail open (both may post). Disable by setting `EVENT_CLAIM_DEDUP_ENABLED` to `false` in source — needed if two configs for the same runner intentionally target **different** collector URLs (the claim key does not include the URL, so only one would deliver).
|
|
76
|
+
|
|
75
77
|
Wired command shape (auth is in the committed `collector_url`). The per-event command is **pinned to the installer's version** (not `@latest`):
|
|
76
78
|
|
|
77
79
|
```bash
|
|
@@ -126,7 +128,7 @@ npx @ev-ai/agent-hook@latest install \
|
|
|
126
128
|
|
|
127
129
|
### Identity and runtime notes
|
|
128
130
|
|
|
129
|
-
Each developer's `installation_id` is created on first hook fire and stored once per machine under `~/.ev-ai/agent-hook/installation.json` (shared across all repos on that machine). Ephemeral CI/cloud homes (no durable `~/.ev-ai`) derive a stable id from platform seeds (e.g. GitHub Actions `GITHUB_REPOSITORY_ID` + `GITHUB_ACTOR`, Codespaces `CODESPACE_NAME`) so collector rows do not churn every run. Pin explicitly with `EV_AI_HOOK_INSTALLATION_ID` (8–64 chars `[A-Za-z0-9._-]`) when the environment has no actor seed
|
|
131
|
+
Each developer's `installation_id` is created on first hook fire and stored once per machine under `~/.ev-ai/agent-hook/installation.json` (shared across all repos on that machine). Ephemeral CI/cloud homes (no durable `~/.ev-ai`) derive a stable id from platform seeds (e.g. GitHub Actions `GITHUB_REPOSITORY_ID` + `GITHUB_ACTOR`, Codespaces `CODESPACE_NAME`, Cursor Cloud `CURSOR_PROJECT_DIR` + `CURSOR_USER_EMAIL`, Claude Code remote origin remote + git author email) so collector rows do not churn every run. Cursor Cloud / Claude remote snapshot images that bake a random `installation.json` are rewritten to that derived id. Pin explicitly with `EV_AI_HOOK_INSTALLATION_ID` (8–64 chars `[A-Za-z0-9._-]`) when the environment has no actor seed.
|
|
130
132
|
|
|
131
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.
|
|
132
134
|
|
|
@@ -147,7 +149,7 @@ For the **plugin** path, do not add ev-ai per-event hooks to `.claude/settings.j
|
|
|
147
149
|
- Teardown events stay in-process (sync POST) — Claude `SessionEnd` / `StopFailure`, Codex `Stop`, and `SubagentStop`, because the runner may kill detached children when the session/worker tree is torn down
|
|
148
150
|
- POST / spawn failures log to stderr only
|
|
149
151
|
|
|
150
|
-
Debug envelope logging: `EV_AI_HOOK_DEBUG=1` (redacted summary). Full envelope: `EV_AI_HOOK_DEBUG=full`. Force all events in-process: `EV_AI_HOOK_SYNC=1`.
|
|
152
|
+
Debug envelope logging: `EV_AI_HOOK_DEBUG=1` (redacted summary). Full envelope: `EV_AI_HOOK_DEBUG=full`. Force all events in-process: `EV_AI_HOOK_SYNC=1`. Disable duplicate-config claim collapsing by setting `EVENT_CLAIM_DEDUP_ENABLED` to `false` in source (use when two configs for the same runner must POST to different collectors).
|
|
151
153
|
|
|
152
154
|
## Privacy defaults
|
|
153
155
|
|
package/dist/cli.mjs
CHANGED
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __createRequire } from 'node:module';
|
|
3
|
+
const require = __createRequire(import.meta.url);
|
|
2
4
|
|
|
3
|
-
import{realpathSync as
|
|
4
|
-
`)}function z(e,t){fo(dn(e),{recursive:!0});let n=mn(dn(e),`.${ho(e)}.${process.pid}.${uo(4).toString("hex")}.tmp`);try{go(n,t,"utf8");try{ln(n,e)}catch(r){let o=r instanceof Error&&"code"in r?r.code:void 0;if(o==="EEXIST"||o==="EPERM"||o==="EACCES"){un(e),ln(n,e);return}throw r}}catch(r){try{un(n)}catch{}throw r}}function Ae(){return new Date().toISOString().replace(/\.\d{3}Z$/,"Z")}function gn(){process.stdout.write('{"continue":true}')}function E(e){let t=process.env[e];return t===void 0||t===""?void 0:t}async function le(){return new Promise(e=>{let t="";if(process.stdin.isTTY){e("");return}process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{t+=n}),process.stdin.on("end",()=>{e(t)}),process.stdin.on("error",()=>{e(t)}),process.stdin.resume()})}async function et(e){return new Promise(t=>{let n="",r=!1,o=i=>{r||(r=!0,clearTimeout(s),t(i||"{}"))},s=setTimeout(()=>{o(n)},e);if(process.stdin.isTTY){o("{}");return}process.stdin.setEncoding("utf8"),process.stdin.on("data",i=>{n+=i}),process.stdin.on("end",()=>{o(n)}),process.stdin.on("error",()=>{o(n)}),process.stdin.resume()})}async function D(e,t,n=3e3,r={}){let{execFile:o}=await import("node:child_process"),{promisify:s}=await import("node:util"),i=s(o);try{let{stdout:a}=await i(e,t,{timeout:n,windowsHide:!0,maxBuffer:1048576,cwd:r.cwd});return{ok:!0,stdout:a.trim()}}catch(a){let c=a,u=typeof c.code=="number"?c.code:typeof c.status=="number"?c.status:void 0;return{ok:!1,code:u,spawnFailed:u===void 0}}}async function C(e,t,n=3e3,r={}){let o=await D(e,t,n,r);return o.ok?o.stdout:""}async function M(e=process.cwd()){return await C("git",["rev-parse","--show-toplevel"],2e3,{cwd:e})||e}function v(e,t){try{return JSON.parse(e)}catch{return t}}var Qe=new Map;function ne(e,t){let n=Qe.get(e);if(n!==void 0)return n;try{let r=v(mo(e,"utf8"),t);return Qe.set(e,r),r}catch{return Qe.set(e,t),t}}function ue(e){return typeof e=="string"?e:""}function Y(e,t){let n=e[t];if(typeof n=="string"||typeof n=="number"||typeof n=="boolean")return n;if(!t.includes("."))return;let r=t.split("."),o=e;for(let s of r){if(o===null||typeof o!="object"||Array.isArray(o))return;o=o[s]}if(typeof o=="string"||typeof o=="number"||typeof o=="boolean")return o}function m(e,t){let n=Y(e,t);return typeof n=="string"?n:""}var X=500;function de(e,t=2){if(!fn(e))return{entries:[],truncated:!1};let n=[],r=!1,o=(s,i)=>{if(i>t||r)return;let a;try{a=po(s,{withFileTypes:!0})}catch{return}for(let c of a){if(r)return;let u=mn(s,c.name);if(c.isDirectory()){o(u,i+1);continue}if(c.isFile()){try{n.push({name:_o(e,u),size:pn(u).size})}catch{continue}if(n.length>=X){r=!0;return}}}};return o(e,1),{entries:n,truncated:r}}function fe(e){return fn(e)?{present:!0,size:pn(e).size}:{present:!1,size:0}}var yo="installation.json",ko="cloud-bootstrap.lock",Io=6e4;function Cn(e,t,n){let r=`${e}:${t??""}`;return n?`${n}:${r}`:r}function ot(e=tt()){return rt(e,".ev-ai","agent-hook")}function Ro(e=tt()){return rt(ot(e),yo)}function xn(e){return rt(nt(e),ko)}function An(){return So(8).toString("hex")}function Te(e){return Sn("sha256").update(e).digest("hex").slice(0,16)}function k(e){if(e===void 0)return null;let t=e.trim();return t.length>0?t:null}function Tn(e){return/^[A-Za-z0-9._-]{8,64}$/.test(e)}function Co(e=process.env){let t=k(e.EV_AI_HOOK_INSTALLATION_ID);if(t){if(!Tn(t)){d(`WARN: ignoring EV_AI_HOOK_INSTALLATION_ID (expected 8\u201364 chars [A-Za-z0-9._-], got length ${t.length})`);return}return t}}function xo(e=process.env){if(k(e.GITHUB_ACTIONS)){let t=k(e.GITHUB_REPOSITORY_ID)??k(e.GITHUB_REPOSITORY),n=k(e.GITHUB_ACTOR)??k(e.GITHUB_TRIGGERING_ACTOR)??k(e.GITHUB_USER);if(t&&n)return Te(`github_actions|${t}|${n}`)}if(k(e.CODESPACES)||k(e.CODESPACE_NAME)){let t=k(e.CODESPACE_NAME);if(t)return Te(`codespaces|${t}`);let n=k(e.GITHUB_REPOSITORY_ID)??k(e.GITHUB_REPOSITORY),r=k(e.GITHUB_USER)??k(e.GITHUB_ACTOR);if(n&&r)return Te(`codespaces|${n}|${r}`)}if(k(e.GITLAB_CI)){let t=k(e.CI_PROJECT_ID)??k(e.CI_PROJECT_PATH),n=k(e.GITLAB_USER_LOGIN)??k(e.GITLAB_USER_EMAIL)??k(e.GITLAB_USER_NAME);if(t&&n)return Te(`gitlab|${t}|${n}`)}return null}function hn(e,t){if(e&&Tn(e))return e;e&&d(`WARN: ignoring installation id override (expected 8\u201364 chars [A-Za-z0-9._-], got length ${e.length})`);let n=Co(t);if(n)return n;let r=xo(t);return r||An()}async function Ao(e){let n=await C("git",["config","--get","remote.origin.url"],2e3,{cwd:e})||Eo(e);return Sn("sha256").update(n).digest("hex").slice(0,16)}function To(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t={};for(let[n,r]of Object.entries(e))typeof r=="string"&&r.length>0&&(t[n]=r);return Object.keys(t).length>0?t:void 0}function Oo(e){try{let t=JSON.parse(e);if(typeof t.installation_id!="string"||t.installation_id.length===0)return;let n=To(t.platform_agent_ids);return{installation_id:t.installation_id,...n?{platform_agent_ids:n}:{},...typeof t.operator_identity_hash=="string"?{operator_identity_hash:t.operator_identity_hash}:{},...typeof t.operator_identity_sent_at=="string"?{operator_identity_sent_at:t.operator_identity_sent_at}:{}}}catch{return}}function q(e){if(En(e))try{return Oo(kn(e,"utf8"))}catch{}}function st(e){return q(e)}function On(e,t,n){let r=q(e);if(!r||r.operator_identity_hash===t&&r.operator_identity_sent_at===n)return;let o={...r,operator_identity_hash:t,operator_identity_sent_at:n};try{z(e,`${JSON.stringify(o,null,2)}
|
|
5
|
-
`)}catch(s){let
|
|
6
|
-
`,{encoding:"utf8",flag:"wx"}),!0}catch(r){if(
|
|
7
|
-
`)}catch(s){let
|
|
8
|
-
`,{encoding:"utf8",flag:"wx"})}function
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
var Fo=Object.create;var fn=Object.defineProperty;var $o=Object.getOwnPropertyDescriptor;var Bo=Object.getOwnPropertyNames;var jo=Object.getPrototypeOf,Go=Object.prototype.hasOwnProperty;var pn=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var Ko=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Jo=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Bo(t))!Go.call(e,o)&&o!==n&&fn(e,o,{get:()=>t[o],enumerable:!(r=$o(t,o))||r.enumerable});return e};var Vo=(e,t,n)=>(n=e!=null?Fo(jo(e)):{},Jo(t||!e||!e.__esModule?fn(n,"default",{value:e,enumerable:!0}):n,e));var qr=Ko(K=>{"use strict";Object.defineProperty(K,"__esModule",{value:!0});K.ComponentKind=void 0;K.normalizeRepositoryRelativePath=Yr;K.nativeKeyForSkillPath=ba;K.serializeComponentIdentity=Xr;K.buildComponentReference=Pa;K.validateComponentReference=Na;var Oa=pn("node:crypto"),Aa=pn("node:path"),xa="cmp1_",Ta=/^cmp1_[A-Za-z0-9_-]{43}$/,va=["/skills/","/skills-cursor/"];K.ComponentKind={SKILL:"SKILL",INTERFACE:"INTERFACE"};function ze(e,t){if(e.length===0)throw new Error(`${t} is required`);return e}function Yr(e){let t=e.replaceAll("\\","/");if(t.startsWith("/")||/^[A-Za-z]:\//.test(t))throw new Error("sourcePath must be repository-relative");let n=Aa.posix.normalize(t).replace(/^\.\//,"");if(n==="."||n===".."||n.startsWith("../"))throw new Error("sourcePath must be repository-relative");return ze(n,"sourcePath")}function ba(e){let t=e.replaceAll("\\","/");for(let n of va){let r=t.split(n)[1]?.split("/")[0];if(r&&r.length>0)return r}return null}function wa(e){return`${Buffer.byteLength(e,"utf8")}:${e}`}function Xr(e){let t=[ze(e.installationRootExternalKey,"installationRootExternalKey"),ze(e.installableKind,"installableKind"),Yr(e.sourcePath),ze(e.nativeKey,"nativeKey")];return Buffer.from(`1|${t.map(wa).join("|")}`,"utf8")}function Pa(e){let t=(0,Oa.createHash)("sha256").update(Xr(e)).digest("base64url");return`${xa}${t}`}function Na(e){return Ta.test(e)}});import{realpathSync as Al}from"node:fs";import{resolve as xl}from"node:path";import{fileURLToPath as Tl,pathToFileURL as vl}from"node:url";var Wo="https://hooks.ev-ai.ai";function Ne(e,t=Wo){let n=t.replace(/\/+$/,""),r=e.trim();return`${n}/${r}/hook`}var Ue=".claude/ev-ai-runtime-report.json",mn="node_modules/@ev-ai/agent-hook/dist/hook.mjs",z="ev-ai-agent-hook",gn="https://cdn.ev-ai.ai/agent-hook",at=`current/${z}`,ct=`.ev-ai/agent-hook/${z}`,_n=5e3,hn=5e3,lt=3e3;var ut=3e3,En=1500,Sn=4*1024,yn=32*1024,zo=4*1024,F="1.0.8",Le=`@ev-ai/agent-hook@${F}`,In="ev-ai runtime report",Rn=["claude","cursor","codex"];import{chmodSync as ar,cpSync as cr,existsSync as B,mkdirSync as xt,readdirSync as zs,readFileSync as Ys,rmSync as Be,symlinkSync as Xs,writeFileSync as qs}from"node:fs";import{homedir as j}from"node:os";import{basename as Zs,dirname as Tt,isAbsolute as Qs,join as y,relative as lr,resolve as sr,sep as ei}from"node:path";import{fileURLToPath as ti}from"node:url";var Yo=new Set(["localhost","127.0.0.1","[::1]","::1"]),kn=/^[A-Za-z0-9._~-]+$/;function Cn(e){for(let t=0;t<e.length;t++){let n=e.charCodeAt(t);if(n<=32||n===127||n===39)return!0}return!1}function Me(e){try{let t=new URL(e);return t.protocol==="https:"?!0:t.protocol==="http:"?Yo.has(t.hostname):!1}catch{return!1}}function pe(e){let t;try{t=new URL(e)}catch{return`invalid URL (got: ${e})`}if(!Me(e))return`must be https (or http on localhost / 127.0.0.1 / ::1) (got: ${e})`;let n=Xo(e);if(!n)return`must end with /{orgToken}/hook (got: ${e})`;if(!kn.test(n))return`org token must match ${kn.source} (got: ${n})`;if(Cn(e))return`must not contain whitespace, control characters, or single quotes (got: ${e})`;if(Cn(t.pathname))return`pathname must not contain whitespace, control characters, or single quotes (got: ${e})`}function me(e){return new URL(e).toString()}function Xo(e){try{let n=new URL(e).pathname.split("/").filter(r=>r.length>0);if(n.length>=2&&n[n.length-1]==="hook"){let r=n[n.length-2];return r.length>0?r:void 0}return}catch{return}}function dt(e){try{let t=new URL(e),n=t.pathname.split("/").filter(r=>r.length>0);return n.length>=2&&n[n.length-1]==="hook"&&(n[n.length-2]="***",t.pathname=`/${n.join("/")}`),t.toString()}catch{return"<invalid-url>"}}function On(e){if(e.collector_url)return e.collector_url;let t=e.repo_ingest_token?.trim();return t?Ne(t):""}import{createHash as Fn,randomBytes as Ss}from"node:crypto";import{existsSync as $n,mkdirSync as St,readFileSync as Bn,unlinkSync as jn,writeFileSync as Gn}from"node:fs";import{homedir as yt}from"node:os";import{dirname as De,join as It,resolve as ys}from"node:path";var qo=new Set(["action@github.com","noreply@github.com","noreply@anthropic.com","cursoragent@cursor.com"]),Zo=new Set(["github-actions","github actions","dependabot","renovate","cursoragent","cursor agent"]);function Q(e,t){let n=(e??"").trim().toLowerCase(),r=(t??"").trim().toLowerCase();if(!n&&!r)return!1;if(n.includes("[bot]")||Zo.has(n)||r.includes("[bot]")||qo.has(r))return!0;if(r.endsWith("@users.noreply.github.com")){let o=r.slice(0,r.indexOf("@")),s=o.includes("+")?o.slice(o.indexOf("+")+1):o;if(s.endsWith("bot")||s.includes("[bot]"))return!0}return!1}import{existsSync as is,readFileSync as as}from"node:fs";import{hostname as Pn,userInfo as cs}from"node:os";import{randomBytes as Qo}from"node:crypto";import{existsSync as pt,mkdirSync as es,readdirSync as ts,readFileSync as ns,renameSync as An,statSync as vn,unlinkSync as xn,writeFileSync as rs}from"node:fs";import{basename as os,dirname as Tn,join as bn,relative as ss}from"node:path";function d(e){process.stderr.write(`[ev-ai-agent-hook] ${e}
|
|
6
|
+
`)}function Y(e,t){es(Tn(e),{recursive:!0});let n=bn(Tn(e),`.${os(e)}.${process.pid}.${Qo(4).toString("hex")}.tmp`);try{rs(n,t,"utf8");try{An(n,e)}catch(r){let o=r instanceof Error&&"code"in r?r.code:void 0;if(o==="EEXIST"||o==="EPERM"||o==="EACCES"){xn(e),An(n,e);return}throw r}}catch(r){try{xn(n)}catch{}throw r}}function He(){return new Date().toISOString().replace(/\.\d{3}Z$/,"Z")}function wn(){process.stdout.write('{"continue":true}')}function k(e){let t=process.env[e];return t===void 0||t===""?void 0:t}async function ge(){return new Promise(e=>{let t="";if(process.stdin.isTTY){e("");return}process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{t+=n}),process.stdin.on("end",()=>{e(t)}),process.stdin.on("error",()=>{e(t)}),process.stdin.resume()})}async function mt(e){return new Promise(t=>{let n="",r=!1,o=a=>{r||(r=!0,clearTimeout(s),t(a||"{}"))},s=setTimeout(()=>{o(n)},e);if(process.stdin.isTTY){o("{}");return}process.stdin.setEncoding("utf8"),process.stdin.on("data",a=>{n+=a}),process.stdin.on("end",()=>{o(n)}),process.stdin.on("error",()=>{o(n)}),process.stdin.resume()})}async function U(e,t,n=3e3,r={}){let{execFile:o}=await import("node:child_process"),{promisify:s}=await import("node:util"),a=s(o);try{let{stdout:i}=await a(e,t,{timeout:n,windowsHide:!0,maxBuffer:1048576,cwd:r.cwd});return{ok:!0,stdout:i.trim()}}catch(i){let c=i,l=typeof c.code=="number"?c.code:typeof c.status=="number"?c.status:void 0;return{ok:!1,code:l,spawnFailed:l===void 0}}}async function C(e,t,n=3e3,r={}){let o=await U(e,t,n,r);return o.ok?o.stdout:""}async function gt(e=process.cwd()){let t=await U("git",["rev-parse","--show-toplevel"],2e3,{cwd:e});if(t.ok&&t.stdout)return{root:t.stdout,inGitRepo:!0};if(k("EV_AI_HOOK_DEBUG")){let r=t.ok?"empty stdout":t.spawnFailed?"spawn failed":`exit ${String(t.code??"unknown")}`;d(`DEBUG: git rev-parse --show-toplevel failed (${r}) cwd=${e}`)}let n=k("CURSOR_PROJECT_DIR")??k("CLAUDE_PROJECT_DIR");if(n&&pt(n)){let r=await U("git",["rev-parse","--show-toplevel"],2e3,{cwd:n});return r.ok&&r.stdout?{root:r.stdout,inGitRepo:!0}:{root:n,inGitRepo:!1}}return{root:e,inGitRepo:!1}}async function $(e=process.cwd()){return(await gt(e)).root}function w(e,t){try{return JSON.parse(e)}catch{return t}}var ft=new Map;function ae(e,t){let n=ft.get(e);if(n!==void 0)return n;try{let r=w(ns(e,"utf8"),t);return ft.set(e,r),r}catch{return ft.set(e,t),t}}function ee(e){return typeof e=="string"?e:""}function te(e,t){let n=e[t];if(typeof n=="string"||typeof n=="number"||typeof n=="boolean")return n;if(!t.includes("."))return;let r=t.split("."),o=e;for(let s of r){if(o===null||typeof o!="object"||Array.isArray(o))return;o=o[s]}if(typeof o=="string"||typeof o=="number"||typeof o=="boolean")return o}function p(e,t){let n=te(e,t);return typeof n=="string"?n:""}var H=500;function _e(e,t=2){if(!pt(e))return{entries:[],truncated:!1};let n=[],r=!1,o=(s,a)=>{if(a>t||r)return;let i;try{i=ts(s,{withFileTypes:!0})}catch{return}for(let c of i){if(r)return;let l=bn(s,c.name);if(c.isDirectory()){o(l,a+1);continue}if(c.isFile()){try{n.push({name:ss(e,l),size:vn(l).size})}catch{continue}if(n.length>=H){r=!0;return}}}};return o(e,1),{entries:n,truncated:r}}function he(e){return pt(e)?{present:!0,size:vn(e).size}:{present:!1,size:0}}function Ee(e){if(e===void 0||e==="")return!1;let t=e.trim().toLowerCase();return t!=="0"&&t!=="false"&&t!=="no"}var ls=["CIRCLECI","BUILDKITE","TF_BUILD","JENKINS_URL","JENKINS_HOME","CODEBUILD_BUILD_ID","DRONE","DRONE_BUILD_NUMBER","TEAMCITY_VERSION","TRAVIS","APPVEYOR","BITBUCKET_BUILD_NUMBER"];function us(e){return ls.some(t=>!!I(t,e))}function ds(e){if(I("KUBERNETES_SERVICE_HOST",e)||Ee(I("REMOTE_CONTAINERS",e))||Ee(I("DEVCONTAINER",e)))return!0;try{if(is("/.dockerenv")||as("/proc/1/environ","utf8").includes("container="))return!0}catch{}return!1}function Nn(e){return["VSCODE_PID","VSCODE_IPC_HOOK","CURSOR_EXTENSION_HOST_ROLE","CURSOR_WORKSPACE_LABEL"].some(t=>!!I(t,e))}function fs(e,t=process.platform){return Nn(e)?t==="darwin"||t==="win32"?!0:["__CFBundleIdentifier","DISPLAY","WAYLAND_DISPLAY","SESSIONNAME"].some(n=>!!I(n,e)):!1}function ps(e){return e===void 0?!1:e.trim().toLowerCase().startsWith("bc-")}function ms(e){return e==="linux"}function I(e,t){if(t){let n=t[e];return n===void 0||n===""?void 0:n}return k(e)}function gs(e,t,n){return e.trim().toLowerCase()==="cursor"&&t.trim().toLowerCase()==="ubuntu"&&!!_s(I("CURSOR_VERSION",n))}function _s(e){if(e===void 0)return null;let t=e.trim();return t.length>0?t:null}function _t(e){if(ps(e.sessionId))return!0;let t=e.hostname??Pn(),n=e.osUser??Un(e.env);return gs(t,n,e.env)}function hs(e){return Ee(I("CURSOR_AGENT",e.env))?!0:_t(e)}function Es(e){return!!(process.stdin.isTTY||process.stdout.isTTY||(I("TERM",e)??I("TERM_PROGRAM",e))||(I("SSH_TTY",e)??I("SSH_CONNECTION",e))||(I("__CFBundleIdentifier",e)??I("XPC_SERVICE_NAME",e))||Nn(e)||["DISPLAY","WAYLAND_DISPLAY","XDG_SESSION_TYPE","DBUS_SESSION_BUS_ADDRESS"].some(t=>!!I(t,e))||I("SESSIONNAME",e))}function Se(e={}){let t=e.env;if(I("GITHUB_ACTIONS",t))return"github_actions";if(Ee(I("CLAUDE_CODE_REMOTE",t)))return"claude_remote";let n=e.platform??process.platform;if(!fs(t,n)&&hs(e)&&(Ee(I("CURSOR_AGENT",t))||ms(n)))return"cursor_cloud";if(I("CODESPACES",t)||I("CODESPACE_NAME",t))return"codespaces";if(I("GITLAB_CI",t))return"gitlab_ci";if(us(t))return"managed";let r=I("CI",t);return r&&r!=="false"&&r!=="0"?"managed":ds(t)?"container":Es(t)?"interactive":"unknown"}async function ht(){return await C("systemd-detect-virt",[],1e3)}function Un(e=process.env,t=cs){for(let n of["USER","LOGNAME","USERNAME"]){let r=e[n];if(typeof r=="string"){let o=r.trim();if(o.length>0)return o}}try{return t().username??""}catch{return""}}async function Et(){let e=process.platform==="darwin"?"Darwin":process.platform==="win32"?"Windows_NT":"Linux",t="";if(process.platform==="darwin")t=await C("sw_vers",["-productVersion"],1e3);else if(process.platform==="linux"){try{let{readFileSync:s}=await import("node:fs"),a=s("/etc/os-release","utf8"),i=a.match(/^PRETTY_NAME="?([^"\n]+)"?/m)?.[1],c=a.match(/^VERSION_ID="?([^"\n]+)"?/m)?.[1];t=i??c??""}catch{t=await C("lsb_release",["-sd"],1e3).then(s=>s.replace(/^"|"$/g,""))}t||(t=await C("uname",["-r"],1e3))}else t=await C("ver",[],1e3);let n=Un(),r=(process.env.SHELL??"").split(/[/\\]/).pop()??"",o="";try{o=await C("tty",[],500),o.includes("not a tty")&&(o="")}catch{o=""}return{os:e,os_version:t||null,user:n||null,shell:r||null,tty:o||null}}function ye(){return Pn()}var Is="installation.json",Rs="cloud-bootstrap.lock",ks=6e4;function Kn(e,t,n){let r=`${e}:${t??""}`;return n?`${n}:${r}`:r}function Ie(e=yt()){return It(e,".ev-ai","agent-hook")}function Cs(e=yt()){return It(Ie(e),Is)}function Jn(e){return It(De(e),Rs)}function Vn(){return Ss(8).toString("hex")}function ce(e){return Fn("sha256").update(e).digest("hex").slice(0,16)}function S(e){if(e===void 0)return null;let t=e.trim();return t.length>0?t:null}function Wn(e){return/^[A-Za-z0-9._-]{8,64}$/.test(e)}function Os(e=process.env){let t=S(e.EV_AI_HOOK_INSTALLATION_ID);if(t){if(!Wn(t)){d(`WARN: ignoring EV_AI_HOOK_INSTALLATION_ID (expected 8\u201364 chars [A-Za-z0-9._-], got length ${t.length})`);return}return t}}function zn(e,t){return e&&Wn(e)?e:(e&&d(`WARN: ignoring installation id override (expected 8\u201364 chars [A-Za-z0-9._-], got length ${e.length})`),Os(t))}function As(e){return/^[0-9a-f]{16}$/.test(e)}function xs(e=process.env){if(S(e.GITHUB_ACTIONS)){let t=S(e.GITHUB_REPOSITORY_ID)??S(e.GITHUB_REPOSITORY),n=S(e.GITHUB_ACTOR)??S(e.GITHUB_TRIGGERING_ACTOR)??S(e.GITHUB_USER);if(t&&n)return ce(`github_actions|${t}|${n}`)}if(S(e.CODESPACES)||S(e.CODESPACE_NAME)){let t=S(e.CODESPACE_NAME);if(t)return ce(`codespaces|${t}`);let n=S(e.GITHUB_REPOSITORY_ID)??S(e.GITHUB_REPOSITORY),r=S(e.GITHUB_USER)??S(e.GITHUB_ACTOR);if(n&&r)return ce(`codespaces|${n}|${r}`)}if(S(e.GITLAB_CI)){let t=S(e.CI_PROJECT_ID)??S(e.CI_PROJECT_PATH),n=S(e.GITLAB_USER_LOGIN)??S(e.GITLAB_USER_EMAIL)??S(e.GITLAB_USER_NAME);if(t&&n)return ce(`gitlab|${t}|${n}`)}return null}var Ts="cursoragent@cursor.com";function vs(e){let t=S(e.CURSOR_USER_EMAIL);return!t||t.toLowerCase()===Ts?null:t}function bs(e,t){return S(e.CURSOR_PROJECT_DIR)??S(e.CLAUDE_PROJECT_DIR)??t}function ws(e){return e.replace(/^([a-z]+:\/\/)[^/@]+@/i,"$1").replace(/\.git$/i,"").toLowerCase()}async function Ps(e){let t=await C("git",["config","--get","remote.origin.url"],2e3,{cwd:e});return t?ws(t):e}async function Ns(e){let t=S(await C("git",["config","--local","--get","user.email"],2e3,{cwd:e})||void 0);if(t&&!Q(null,t))return t;let n=S(await C("git",["log","-1","--format=%ae"],2e3,{cwd:e})||void 0);return n&&!Q(null,n)?n:null}function Us(e,t){let n=bs(e,t);return n?ce(`cursor_cloud|${n}|${vs(e)??""}`):null}async function Ls(e,t){let n=S(e.CLAUDE_PROJECT_DIR)??t;if(!n)return null;let r=await Ps(n),o=await Ns(n);return ce(`claude_remote|${r}|${o??""}`)}function Ln(e,t){let n=zn(e,t);if(n)return n;let r=xs(t);return r||Vn()}async function Ms(e){let n=await C("git",["config","--get","remote.origin.url"],2e3,{cwd:e})||ys(e);return Fn("sha256").update(n).digest("hex").slice(0,16)}function Hs(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t={};for(let[n,r]of Object.entries(e))typeof r=="string"&&r.length>0&&(t[n]=r);return Object.keys(t).length>0?t:void 0}function Ds(e){try{let t=JSON.parse(e);if(typeof t.installation_id!="string"||t.installation_id.length===0)return;let n=Hs(t.platform_agent_ids);return{installation_id:t.installation_id,...t.pinned===!0?{pinned:!0}:{},...n?{platform_agent_ids:n}:{},...typeof t.operator_identity_hash=="string"?{operator_identity_hash:t.operator_identity_hash}:{},...typeof t.operator_identity_sent_at=="string"?{operator_identity_sent_at:t.operator_identity_sent_at}:{}}}catch{return}}function ne(e){if($n(e))try{return Ds(Bn(e,"utf8"))}catch{}}function Rt(e){return ne(e)}function Yn(e,t,n){let r=ne(e);if(!r||r.operator_identity_hash===t&&r.operator_identity_sent_at===n)return;let o={...r,operator_identity_hash:t,operator_identity_sent_at:n};try{Y(e,`${JSON.stringify(o,null,2)}
|
|
7
|
+
`)}catch(s){let a=s instanceof Error?s.message:String(s);d(`WARN: operator identity cache write failed open: ${a}`)}}function Xn(e,t=Date.now()){if(!e)return!0;if(ne(e)?.operator_identity_hash)return!1;let n=Jn(e);try{if($n(n)){let r=Number.NaN;try{r=Number(Bn(n,"utf8").trim())}catch{}let o=t-r;if(Number.isFinite(o)&&o>=0&&o<ks)return!1;try{jn(n)}catch{}}}catch{}try{return St(De(n),{recursive:!0}),Gn(n,`${t}
|
|
8
|
+
`,{encoding:"utf8",flag:"wx"}),!0}catch(r){if(er(r))return!1;let o=r instanceof Error?r.message:String(r);return d(`WARN: cloud bootstrap claim failed open: ${o}`),!0}}function qn(e){if(e)try{jn(Jn(e))}catch{}}function Zn(e,t){let r=ne(e)?.platform_agent_ids?.[t];return typeof r=="string"&&r.length>0?r:void 0}function Qn(e,t,n){if(!n)return;let r=ne(e);if(!r||r.platform_agent_ids?.[t]===n)return;let o={installation_id:r.installation_id,platform_agent_ids:{...r.platform_agent_ids,[t]:n},...r.operator_identity_hash?{operator_identity_hash:r.operator_identity_hash}:{},...r.operator_identity_sent_at?{operator_identity_sent_at:r.operator_identity_sent_at}:{}};try{Y(e,`${JSON.stringify(o,null,2)}
|
|
9
|
+
`)}catch(s){let a=s instanceof Error?s.message:String(s);d(`WARN: platform_agent_id cache write failed open: ${a}`)}}function er(e){return e instanceof Error&&"code"in e&&e.code==="EEXIST"}function Fs(e,t){St(De(e),{recursive:!0}),Gn(e,`${JSON.stringify(t,null,2)}
|
|
10
|
+
`,{encoding:"utf8",flag:"wx"})}function Mn(e,t){try{return Fs(e,t),t}catch(n){if(!er(n))throw n;return ne(e)}}function Hn(e,t){St(De(e),{recursive:!0}),Y(e,`${JSON.stringify(t,null,2)}
|
|
11
|
+
`)}function Dn(e,t){return{installation_id:e,...t&&t===e?{pinned:!0}:{}}}async function Fe(e,t={}){let n=t.home??yt(),r=t.env??process.env,o=await Ms(e),s=Cs(n),a={sessionId:t.sessionId,hostname:S(r.HOSTNAME)??void 0,osUser:S(r.USER)??S(r.LOGNAME)??S(r.USERNAME)??void 0,env:r},i=Se(a),c=zn(t.overrideId,r),l=i==="cursor_cloud"&&_t(a)?Us(r,e):i==="claude_remote"?await Ls(r,e):null,u=ne(s);if(u){let E=u;if(c&&c===u.installation_id&&u.pinned!==!0&&(E={...u,pinned:!0},Hn(s,E)),!!l&&l!==E.installation_id&&!c&&E.pinned!==!0&&As(E.installation_id)&&l){let A={installation_id:l,...E.platform_agent_ids?{platform_agent_ids:E.platform_agent_ids}:{}};return Hn(s,A),{installationId:l,storePath:s,repoKey:o}}return{installationId:E.installation_id,storePath:s,repoKey:o}}let f=c??l??Ln(void 0,r),g=Mn(s,Dn(f,c));if(g)return{installationId:g.installation_id,storePath:s,repoKey:o};let m=c??l??Ln(void 0,r),_=Mn(s,Dn(m===f?Vn():m,c));if(_)return{installationId:_.installation_id,storePath:s,repoKey:o};throw new Error(`Failed to create installation record at ${s}`)}import{existsSync as kt,readFileSync as $s}from"node:fs";import{dirname as Bs,join as tr,relative as js}from"node:path";var $e=[Ue,".cursor/ev-ai-runtime-report.json",".codex/ev-ai-runtime-report.json"];async function Gs(e=process.cwd(),t){let n=k("EV_AI_HOOK_MANIFEST");if(n&&kt(n))return n;let r=t??await $(e);for(let o of $e){let s=tr(r,o);if(kt(s))return s}for(let o of $e){let s=tr(e,o);if(kt(s))return s}}async function Ks(e,t){let n=t??await $(Bs(e)),r=js(n,e),o=await U("git",["ls-files","--error-unmatch",r],2e3,{cwd:n});return o.ok?!0:o.code===1?!1:(d(`WARN: git ls-files failed for manifest ${e} (code=${String(o.code)}); treating as tracked`),!0)}function Js(e){let t=$s(e,"utf8");return w(t,{})}function Vs(){return{schema_version:2,mcp_servers:[]}}async function nr(e=process.cwd(),t={}){let{root:n,inGitRepo:r}=await gt(e),o=await Gs(e,n),s=o?Js(o):Vs();delete s.installation_id;let a=o?await Ks(o,n):!1;s.capture_hook_input==="full"&&o&&a&&(d(`WARN: ignoring capture_hook_input=full in git-tracked manifest ${o}; use EV_AI_HOOK_CAPTURE_FULL_INPUT=1 or an untracked operator manifest`),delete s.capture_hook_input);let{installationId:i,storePath:c,repoKey:l}=await Fe(n,{sessionId:t.sessionId});return{manifestPath:o??c,manifest:s,installationId:i,installationStorePath:c,repoKey:l,collectorUrl:On(s),platformAgentId:s.platform_agent_id??"",gitRoot:n,inGitRepo:r}}function rr(e){return{schema_version:2,...e?{collector_url:e}:{},mcp_servers:[]}}var Ws=["darwin-arm64","darwin-x64","linux-arm64","linux-x64"];function Ct(e=process.platform,t=process.arch){if(e==="darwin")return t==="arm64"?"darwin-arm64":t==="x64"?"darwin-x64":void 0;if(e==="linux")return t==="arm64"?"linux-arm64":t==="x64"?"linux-x64":void 0}function or(e=process.platform,t=process.arch){let n=Ct(e,t);if(!n)throw new Error(`Unsupported platform ${e}-${t}. Supported: ${Ws.join(", ")}.`);return n}function Ot(e){return`compile-out/bin/${e}/ev-ai-agent-hook`}function ni(e,t){let n=e.collectorUrl?.trim();if(!n)throw new Error(`${t} requires --url <https://hooks.ev-ai.ai/{orgToken}/hook>`);let r=pe(n);if(r)throw new Error(`collector URL rejected: ${r}`);return me(n)}function ri(e){let t=e.collectorUrl?.trim();if(!t)return;let n=pe(t);if(n)throw new Error(`collector URL rejected: ${n}`);return me(t)}function oi(e){return ni(e,"install")}function ur(e){let t={};for(let n=0;n<e.length;n++){let r=e[n];if(r==="--url"){let o=e[n+1];o&&!o.startsWith("--")&&(t.collectorUrl=o,n+=1);continue}if(r==="--collector-url")throw new Error("--collector-url was renamed to --url")}return t}function dr(e){let t={};for(let n=0;n<e.length;n++){let r=e[n];if(r==="--url"){let o=e[n+1];o&&!o.startsWith("--")&&(t.collectorUrl=o,n+=1);continue}if(r==="--collector-url")throw new Error("--collector-url was renamed to --url");if(r==="--update")throw new Error("--update was removed; use the `update` command instead of `install --update`");if(r==="--delivery"){let o=e[n+1];(o==="npx"||o==="binary"||o==="local")&&(t.delivery=o,n+=1);continue}if(r==="--force"){t.force=!0;continue}if(r==="--no-claude"){t.skipClaude=!0;continue}if(r==="--no-cursor"){t.skipCursor=!0;continue}if(r==="--no-codex"){t.skipCodex=!0;continue}}return t}function fr(e=process.execPath){return pr(e)?"binary":"npx"}function si(){return y(j(),".ev-ai","agent-hook")}function ii(e=j()){return y(e,".ev-ai","agent-hook",at)}function ai(){let e=Tt(ti(import.meta.url)),t=y(e,"hook.mjs");return B(t)?t:y(e,"..","dist","hook.mjs")}function pr(e=process.execPath){return Zs(e)===z}function mr(e,t){let n=lr(sr(e),sr(t));return!n.startsWith("..")&&!Qs(n)}function je(e){return e.split(ei).join("/")}function ci(e){return`node "$(git rev-parse --show-toplevel)/${je(e)}"`}function li(e){return`"$(git rev-parse --show-toplevel)/${je(e)}"`}function ui(e){return y(e,ct)}function gr(e,t){let n=ui(e);xt(Tt(n),{recursive:!0}),cr(t,n,{force:!0});try{ar(n,493)}catch{}return n}function di(e){let t=y(si(),"current");try{Be(t,{recursive:!0,force:!0})}catch{}Xs(e,t,process.platform==="win32"?"junction":"dir")}function _r(e,t=F,n=j()){let r=y(n,".ev-ai","agent-hook",t),o=y(r,z);xt(r,{recursive:!0}),cr(e,o,{force:!0});try{ar(o,493)}catch{}return di(r),y(n,".ev-ai","agent-hook",at)}function hr(e){let t=Ct();if(!t)return;let n=[y(e,Ot(t)),y(e,"packages","agent-hook",Ot(t))];for(let r of n)if(B(r)&&mr(e,r))return r}function fi(e=j()){let t=ii(e);return B(t)?t:void 0}function pi(e,t=j()){let n=fi(t);return n||(pr()?_r(process.execPath,F,t):hr(e))}function mi(e,t=j()){let n=hr(e);if(!n)throw new Error(`update requires a locally compiled binary \u2014 run this package\u2019s build:hook-binary script first.
|
|
12
|
+
To install a released binary instead: curl -fsSL https://cdn.ev-ai.ai/agent-hook/install.sh | sh`);let r=_r(n,F,t),o=gr(e,n);return{sourcePath:n,projectPath:o,globalPath:r}}function ir(e){let t=[y(e,"packages","agent-hook","dist","hook.mjs"),y(e,mn)],n=ai();B(n)&&mr(e,n)&&t.unshift(n);for(let r of t){if(!B(r))continue;let o=je(lr(e,r));return{command:ci(o),hookPath:o,strategy:"dev_mjs"}}}function gi(e=Le){return`npx -y ${e}`}function _i(e,t=j(),n=fr()){if(n==="npx")return{command:gi(),hookPath:Le,strategy:"npx"};if(n==="local"){let s=ir(e);if(s)return s;throw new Error("local delivery requires packages/agent-hook/dist/hook.mjs (or node_modules/@ev-ai/agent-hook/dist/hook.mjs) under the git root \u2014 run yarn workspace @ev-ai/agent-hook build first")}let r=pi(e,t);if(r){gr(e,r);let s=je(ct);return{command:li(s),hookPath:s,strategy:"project_binary"}}let o=ir(e);if(o)return o;throw new Error(`ev-ai-agent-hook binary not found. Install from CDN:
|
|
13
|
+
curl -fsSL ${gn}/install.sh | sh
|
|
11
14
|
Or use npx delivery:
|
|
12
|
-
npx ${
|
|
13
|
-
`,"utf8")}function B(e){if(F(e))try{return JSON.parse(Fo(e,"utf8"))}catch(t){throw t instanceof SyntaxError?new Error(`Invalid JSON in ${e} \u2014 fix or remove the file`,{cause:t}):t}}function as(e,t){let n=Ln(t.collectorUrl),r={...e,schema_version:e?.schema_version??n.schema_version};return t.collectorUrl!==void 0?r.collector_url=t.collectorUrl:r.collector_url=e?.collector_url??n.collector_url,delete r.repo_ingest_token,delete r.installation_id,r.mcp_servers??=n.mcp_servers,r}function cs(e){return(e.schema_version??2)===2&&e.collector_url===void 0&&(e.mcp_servers?.length??0)===0&&e.platform_agent_id===void 0&&e.capture_hook_input===void 0&&e.repo_ingest_token===void 0}function Zn(e,t){let n=h(e,Re),r=B(n),o=as(r,t);return t.collectorUrl!==void 0||F(n)||!cs(o)?(V(n,o),{manifestPath:n,wrote:!0}):{manifestPath:void 0,wrote:!1}}function lt(e){if(e===null||typeof e!="object")return!1;let t=e,n=String(t.CLAUDE_CODE_ENABLE_TELEMETRY??"").toLowerCase();return n==="1"||n==="true"?!0:Object.keys(t).some(r=>r.startsWith("OTEL_"))}function ls(e=process.platform){switch(e){case"darwin":return"/Library/Application Support/ClaudeCode";case"win32":return h(process.env.ProgramFiles??"C:\\Program Files","ClaudeCode");default:return"/etc/claude-code"}}function us(e=process.platform){let t=ls(e),n=[h(t,"managed-settings.json")],r=h(t,"managed-settings.d");try{if(!F(r))return n;let o=Do(r).filter(s=>s.endsWith(".json")&&!s.startsWith(".")).sort().map(s=>h(r,s));n.push(...o)}catch{}return n}function ds(e){if(lt(process.env))return!0;let t=j();return[...us(),h(t,".claude","settings.json"),h(t,".claude","remote-settings.json"),h(e,".claude","settings.json"),h(e,".claude","settings.local.json")].some(r=>{try{let o=B(r);return o?lt(o.env):!1}catch{return!1}})}function fs(e){try{let t=B(h(e,".claude","settings.json"));return t?lt(t.env):!1}catch{return!1}}function Qn(e){return Array.isArray(e)?e:[]}function Ue(e){let t=[],n=r=>!!r&&typeof r=="object"&&qn(r.command);for(let r of Qn(e)){if(!r||typeof r!="object"){t.push(r);continue}let o=Array.isArray(r.hooks)?r.hooks:[],s=o.filter(i=>!n(i));if(!(s.length===0&&o.some(n))){if(s.length!==o.length){t.push({...r,hooks:s});continue}t.push(r)}}return t}function er(e,t){return[...Ue(e),...t]}function pt(e){return Array.isArray(e)?e.filter(t=>!t||typeof t!="object"?!0:!qn(t.command)):[]}function ps(e,t){return[...pt(e),{command:t}]}function ms(e){let t=()=>({hooks:[{type:"command",command:e}]});return{SessionStart:[t()],UserPromptExpansion:[t()],PreToolUse:[t()],PostToolUse:[t()],PostToolUseFailure:[t()],PermissionDenied:[t()],Stop:[t()],StopFailure:[t()],SessionEnd:[t()],SubagentStart:[t()],SubagentStop:[t()]}}function gs(e){let t={type:"command",command:e,statusMessage:rn},n=()=>({hooks:[t]});return{SessionStart:[n()],UserPromptSubmit:[n()],PreToolUse:[n()],PostToolUse:[n()],Stop:[n()]}}var hs=["sessionStart","beforeSubmitPrompt","preToolUse","postToolUse","postToolUseFailure","subagentStart","subagentStop","stop"],_s=["beforeMCPExecution","beforeShellExecution","afterFileEdit"];function Ss(e){let t={...e};for(let n of _s){if(!(n in t))continue;let r=pt(t[n]);r.length===0?delete t[n]:t[n]=r}return t}function Es(e,t,n={}){let r=h(e,".claude/settings.json"),o=ft(t,"claude"),s=B(r)??{};if(ds(e)&&!n.force){if(s.hooks&&typeof s.hooks=="object"){let l={...s.hooks};for(let f of Object.keys(l))l[f]=Ue(l[f]),Qn(l[f]).length===0&&delete l[f];Object.keys(l).length===0?delete s.hooks:s.hooks=l,V(r,s)}return!1}let a=s.hooks&&typeof s.hooks=="object"?s.hooks:{},c=ms(o),u={...a};for(let[l,f]of Object.entries(c))u[l]=er(a[l],f);return s.hooks=u,V(r,s),!0}function ys(e,t){let n=h(e,".cursor/hooks.json"),r=ft(t,"cursor"),o=B(n)??{},s=o.hooks&&typeof o.hooks=="object"?o.hooks:{},i=Ss({...s});for(let a of hs)i[a]=ps(i[a],r);V(n,{...o,version:typeof o.version=="number"?o.version:1,hooks:i})}function ks(e,t){let n=h(e,".codex/hooks.json"),r=ft(t,"codex"),o=B(n)??{},s=o.hooks&&typeof o.hooks=="object"?o.hooks:{},i=gs(r),a={...s};for(let[c,u]of Object.entries(i))a[c]=er(s[c],u);V(n,{...o,hooks:a})}function Is(e){let t=h(e,".claude/settings.json"),n=B(t);if(!n?.hooks||typeof n.hooks!="object")return;let r={...n.hooks},o=!1;for(let s of Object.keys(r)){let i=r[s],a=Ue(i);JSON.stringify(i)!==JSON.stringify(a)&&(o=!0),a.length===0?delete r[s]:r[s]=a}o&&(Object.keys(r).length===0?delete n.hooks:n.hooks=r,V(t,n),d(`Removed ev-ai hooks from ${t}`))}function Rs(e){let t=h(e,".cursor/hooks.json"),n=B(t);if(!n?.hooks||typeof n.hooks!="object")return;let r={...n.hooks},o=!1,s=0;for(let i of Object.keys(r)){let a=r[i],c=pt(a);JSON.stringify(a)!==JSON.stringify(c)&&(o=!0),c.length===0?delete r[i]:(r[i]=c,s+=c.length)}if(o){if(s===0&&Object.keys(r).length===0&&Object.keys(n).filter(a=>a!=="hooks"&&a!=="version").length===0){be(t,{force:!0}),d(`Removed ${t}`);return}V(t,{...n,hooks:r}),d(`Removed ev-ai hooks from ${t}`)}}function Cs(e){let t=h(e,".codex/hooks.json"),n=B(t);if(!n?.hooks||typeof n.hooks!="object")return;let r={...n.hooks},o=!1,s=0;for(let i of Object.keys(r)){let a=r[i],c=Ue(a);JSON.stringify(a)!==JSON.stringify(c)&&(o=!0),c.length===0?delete r[i]:(r[i]=c,s+=c.length)}if(o){if(s===0&&Object.keys(r).length===0&&Object.keys(n).filter(a=>a!=="hooks").length===0){be(t,{force:!0}),d(`Removed ${t}`);return}V(t,{...n,hooks:r}),d(`Removed ev-ai hooks from ${t}`)}}function mt(e=process.platform,t=process.arch,n={}){if(e==="win32")throw new Error("Windows install is not supported yet. Use macOS/Linux, or wait for phase-2 native commands.");(n.requireBinaryArch??!0)&&Hn(e,t)}async function tr(e={}){let t=zo(e);e.collectorUrl=t;let n=e.skipClaude===!0,r=e.skipCursor===!0,o=e.skipCodex===!0;if(n&&r&&o)throw new Error("at least one runner must be wired; refuse --no-claude --no-cursor --no-codex together");let s=e.delivery??Jn();mt(process.platform,process.arch,{requireBinaryArch:s==="binary"});let i=e.cwd??process.cwd(),a=await M(i),{command:c,hookPath:u,strategy:l}=is(a,j(),s),{installationId:f,storePath:g}=await Oe(a,{overrideId:e.installationId}),{manifestPath:p,wrote:_}=Zn(a,e),R=[];return n?d("Skipped Claude hook \u2014 --no-claude"):Es(a,c,{force:e.force})?(R.push("Claude"),e.force&&fs(a)&&d("Forced Claude hook despite project native OTEL \u2014 expect duplicate session/tool events")):d("Skipped Claude hook \u2014 native OTEL telemetry already enabled (avoids duplicate events); pass --force to wire anyway"),r?d("Skipped Cursor hook \u2014 --no-cursor"):(ys(a,c),R.push("Cursor")),o?d("Skipped Codex hook \u2014 --no-codex"):(ks(a,c),R.push("Codex")),d(`Installed hook (${l}) at ${u}`),d(`Installation identity ${f} at ${g}`),_&&p?d(`Shared manifest written to ${p}`):d("Using package default collector config (no shared manifest file needed)"),d(R.length>0?`Wired ${R.join(", ")} hooks in ${a} (commands include --runner)`:`No runner hooks wired in ${a} (Claude skipped by OTEL; Cursor/Codex excluded via flags)`),l==="npx"?d("Hook commands use npx and may be committed; teammates need Node on PATH only (no install step, no env vars when collector_url is in the shared manifest)."):l==="project_binary"?d("Hook commands are git-root-relative and may be committed; each collaborator runs install once to populate .ev-ai/agent-hook/ (gitignored)."):l==="dev_mjs"&&d("Hook commands use node + monorepo packages/agent-hook/dist/hook.mjs (local delivery; rebuild with yarn workspace @ev-ai/agent-hook build)."),_&&p&&e.collectorUrl&&d("Shared manifest includes collector_url \u2014 commit it with hook configs so teammates post without env vars."),{gitRoot:a,hookPath:u,manifestPath:p,installationStorePath:g,strategy:l}}async function nr(e=process.cwd()){mt(process.platform,process.arch,{requireBinaryArch:!0});let t=await M(e),{projectPath:n,globalPath:r}=os(t);d(`Refreshed ${r}`),d(`Refreshed ${n}`),d("Hook configs and shared manifest left unchanged")}async function rr(e={}){let t=Wo(e);e.collectorUrl=t,mt(process.platform,process.arch,{requireBinaryArch:!1});let n=e.cwd??process.cwd(),r=await M(n),{manifestPath:o,wrote:s}=Zn(r,e);if(t!==void 0&&(!o||!s))throw new Error("configure failed to write shared collector manifest");return s&&o?d(`Wrote ${o}`):t===void 0&&d("No --url given and no shared manifest yet \u2014 pass --url <\u2026/{orgToken}/hook> to write collector destination."),d("Manifest only \u2014 enable ev-ai marketplace plugins. Do not also run file-wiring install for the same events."),{gitRoot:r,manifestPath:o}}function or(e){for(let t of[()=>Is(e),()=>Rs(e),()=>Cs(e)])try{t()}catch(n){let r=n instanceof Error?n.message:String(n);d(`WARN: strip skipped a hook file: ${r}`)}}async function sr(e=process.cwd()){let t=await M(e);return or(t),d("Stripped ev-ai file-wired hooks; shared collector manifest left in place."),d("Next: enable ev-ai marketplace plugins, then restart runners."),{gitRoot:t}}async function ir(e=process.cwd()){let t=await M(e);or(t);for(let n of ve){let r=h(t,n);if(F(r))try{be(r,{force:!0}),d(`Removed ${r}`)}catch(o){let s=o instanceof Error?o.message:String(o);d(`WARN: uninstall could not remove ${r}: ${s}`)}}}var xs={claude:".claude",cursor:".cursor",codex:".codex"};function pe(e){let n=e.replace(/^\/+|\/+$/g,"").toLowerCase().split("/").filter(Boolean);return n.length<2?"":n.join("/")}function As(e){if(!e)return"";let t=e.replace(/^([a-z]+:\/\/)[^/@]+@/i,"$1");t=t.replace(/\.git$/i,"");let n=t.match(/^git@[^:]+:(.+)$/);if(n?.[1])return pe(n[1]);let r=t.match(/^ssh:\/\/[^/]+\/(.+)$/i);if(r?.[1])return pe(r[1]);t=t.replace(/^https:\/\//i,""),t=t.replace(/^http:\/\//i,""),t=t.replace(/^ssh:\/\//i,"");let o=t.match(/^[^/]+\/(.+)$/);return o?.[1]?pe(o[1]):pe(t)}async function me(e=process.cwd()){let t=await D("git",["rev-parse","--is-inside-work-tree"],2e3,{cwd:e});if(!t.ok||t.stdout!=="true")return null;let[n,r,o,s]=await Promise.all([D("git",["remote","get-url","origin"],2e3,{cwd:e}),D("git",["branch","--show-current"],2e3,{cwd:e}),D("git",["rev-parse","HEAD"],2e3,{cwd:e}),D("git",["status","--porcelain"],2e3,{cwd:e})]),i=n.ok?n.stdout:null;return{remote:i===null?null:i.replace(/^([a-z]+:\/\/)[^/@]+@/i,"$1"),branch:r.ok?r.stdout:null,head:o.ok?o.stdout:null,dirty:s.ok?s.stdout.length>0:null}}async function ar(e,t,n,r=process.cwd(),o,s,i){if(t)return t;let a=xs[n];if(!a)return"";let c=Cn(n,e.scope_path,i);if(s){let _=wn(s,c);if(_)return _}let u=o??await me(r),l=u?.remote?As(u.remote):"";if(l||(l=pe(process.env.GITHUB_REPOSITORY??"")),!l)return"";let f=e.scope_path??"",g=f?`${f}/`:"",p=`${l}:${g}${a}`;return s&&Un(s,c,p),p}import{existsSync as Ts,readFileSync as Os}from"node:fs";import{hostname as vs,userInfo as bs}from"node:os";function Pe(e){if(e===void 0||e==="")return!1;let t=e.trim().toLowerCase();return t!=="0"&&t!=="false"&&t!=="no"}var ws=["GITLAB_CI","CIRCLECI","BUILDKITE","TF_BUILD","JENKINS_URL","JENKINS_HOME","CODEBUILD_BUILD_ID","DRONE","DRONE_BUILD_NUMBER","TEAMCITY_VERSION","TRAVIS","APPVEYOR","BITBUCKET_BUILD_NUMBER"];function Us(){return ws.some(e=>!!E(e))}function Ps(){if(E("KUBERNETES_SERVICE_HOST")||Pe(E("REMOTE_CONTAINERS"))||Pe(E("DEVCONTAINER")))return!0;try{if(Ts("/.dockerenv")||Os("/proc/1/environ","utf8").includes("container="))return!0}catch{}return!1}function gt(){if(E("GITHUB_ACTIONS"))return"github_actions";if(Pe(E("CLAUDE_CODE_REMOTE")))return"claude_remote";if(Pe(E("CURSOR_AGENT")))return"cursor_cloud";if(E("CODESPACES")||E("CODESPACE_NAME"))return"codespaces";if(Us())return"managed";let e=E("CI");return e&&e!=="false"&&e!=="0"?"managed":Ps()?"container":process.stdin.isTTY||process.stdout.isTTY||E("TERM")?"interactive":"cron"}async function ht(){return await C("systemd-detect-virt",[],1e3)}function Ns(e=process.env,t=bs){for(let n of["USER","LOGNAME","USERNAME"]){let r=e[n];if(typeof r=="string"){let o=r.trim();if(o.length>0)return o}}try{return t().username??""}catch{return""}}async function _t(){let e=process.platform==="darwin"?"Darwin":process.platform==="win32"?"Windows_NT":"Linux",t="";if(process.platform==="darwin")t=await C("sw_vers",["-productVersion"],1e3);else if(process.platform==="linux"){try{let{readFileSync:s}=await import("node:fs"),i=s("/etc/os-release","utf8"),a=i.match(/^PRETTY_NAME="?([^"\n]+)"?/m)?.[1],c=i.match(/^VERSION_ID="?([^"\n]+)"?/m)?.[1];t=a??c??""}catch{t=await C("lsb_release",["-sd"],1e3).then(s=>s.replace(/^"|"$/g,""))}t||(t=await C("uname",["-r"],1e3))}else t=await C("ver",[],1e3);let n=Ns(),r=(process.env.SHELL??"").split(/[/\\]/).pop()??"",o="";try{o=await C("tty",[],500),o.includes("not a tty")&&(o="")}catch{o=""}return{os:e,os_version:t||null,user:n||null,shell:r||null,tty:o||null}}function St(){return vs()}import{existsSync as Ms,readFileSync as Ls}from"node:fs";import{homedir as cr}from"node:os";import{join as Hs}from"node:path";var Ds="cloud-cache.json",Fs=1440*60*1e3,js=900*1e3;function Bs(e=cr()){return Hs(ot(e),Ds)}function $s(e){if(!Ms(e))return;let t=v(Ls(e,"utf8"),{});if(!(typeof t.context!="string"||typeof t.probed_at!="number"||t.result!==null&&t.result!==void 0&&typeof t.result!="object"))return{context:t.context,probed_at:t.probed_at,result:t.result??null}}function Gs(e,t){try{z(e,`${JSON.stringify(t)}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
`)){let o=r.trim();if(!o)continue;let s=o.indexOf(" ");if(s<=0)continue;let i=o.slice(0,s).toLowerCase(),a=o.slice(s+1).trim();a&&(i==="user.name"?t=a:i==="user.email"&&(n=a))}return{git_user_name:t,git_user_email:n,platform_login:null}}async function ri(e,t=C){let n=await t("git",["config","--get-regexp","^user\\.(name|email)$"],2e3,{cwd:e});return ni(n)}function oi(e=process.env){let t=S(e.GIT_AUTHOR_NAME),n=S(e.GIT_AUTHOR_EMAIL);if(t||n)return{git_user_name:t,git_user_email:n,platform_login:null,identity_source:"git_env"};let r=S(e.GIT_COMMITTER_NAME),o=S(e.GIT_COMMITTER_EMAIL);if(r||o)return{git_user_name:r,git_user_email:o,platform_login:null,identity_source:"git_env"};let s=S(e.EMAIL);return s?{git_user_name:null,git_user_email:s,platform_login:null,identity_source:"git_env"}:null}async function si(e,t=C){let n=await t("git",["log","-1","--format=%an%x00%ae"],2e3,{cwd:e});if(!n)return null;let r=n.indexOf("\0"),o=(r>=0?n.slice(0,r):n).trim(),s=(r>=0?n.slice(r+1):"").trim();return!o&&!s?null:{git_user_name:o||null,git_user_email:s||null,platform_login:null,identity_source:"git_log"}}function G(e,t,n,r=null){return!e&&!t&&!r?null:{git_user_name:e,git_user_email:t,platform_login:r,identity_source:n}}function ii(e=process.env){let t=G(S(e.EV_AI_HOOK_OPERATOR_NAME),S(e.EV_AI_HOOK_OPERATOR_EMAIL),"configured");if(t)return t;let n=S(e.GITHUB_ACTOR)??S(e.GITHUB_TRIGGERING_ACTOR)??S(e.GITHUB_USER),r=G(n,null,"github",n);if(r)return r;let o=S(e.GITLAB_USER_LOGIN),s=G(S(e.GITLAB_USER_NAME)??o,S(e.GITLAB_USER_EMAIL),"gitlab",o);if(s)return s;let i=G(S(e.BUILD_REQUESTEDFOR),S(e.BUILD_REQUESTEDFOREMAIL),"azure_devops");if(i)return i;let a=G(S(e.BUILDKITE_BUILD_CREATOR),S(e.BUILDKITE_BUILD_CREATOR_EMAIL),"buildkite");if(a)return a;let c=G(S(e.BUILD_USER)??S(e.CHANGE_AUTHOR),S(e.BUILD_USER_EMAIL)??S(e.CHANGE_AUTHOR_EMAIL),"jenkins",S(e.BUILD_USER_ID));if(c)return c;let u=S(e.CIRCLE_USERNAME),l=G(u,null,"circleci",u);if(l)return l;let f=S(e.CODEBUILD_INITIATOR),g=G(f,null,"codebuild",f);if(g)return g;let p=G(S(e.DRONE_COMMIT_AUTHOR)??S(e.DRONE_COMMIT_AUTHOR_NAME),S(e.DRONE_COMMIT_AUTHOR_EMAIL),"drone",S(e.DRONE_COMMIT_AUTHOR));return p||(ur(e.CLAUDE_CODE_REMOTE)||ur(e.CURSOR_AGENT)?{git_user_name:null,git_user_email:null,platform_login:null,identity_source:"cloud"}:null)}function xt(e){return!!((e.git_user_name??e.git_user_email)&&!li(e.git_user_name,e.git_user_email))}function S(e){if(e===void 0)return null;let t=e.trim();return t.length>0?t:null}function ur(e){if(e===void 0||e==="")return!1;let t=e.trim().toLowerCase();return t!=="0"&&t!=="false"&&t!=="no"}var ai=new Set(["action@github.com","noreply@github.com","noreply@anthropic.com","cursoragent@cursor.com"]),ci=new Set(["github-actions","github actions","dependabot","renovate","cursoragent","cursor agent"]);function li(e,t){let n=(e??"").trim().toLowerCase(),r=(t??"").trim().toLowerCase();if(!n&&!r)return!1;if(n.includes("[bot]")||ci.has(n)||r.includes("[bot]")||ai.has(r))return!0;if(r.endsWith("@users.noreply.github.com")){let o=r.slice(0,r.indexOf("@")),s=o.includes("+")?o.slice(o.indexOf("+")+1):o;if(s.endsWith("bot")||s.includes("[bot]"))return!0}return!1}async function ui(e,t=C,n=process.env){let r=await ri(e,t);if(xt(r))return{...r,identity_source:"git_config"};let o=oi(n);if(o&&xt(o))return o;let s=ii(n);if(s&&(s.git_user_name||s.git_user_email||s.platform_login))return s;let i=await si(e,t);return i&&xt(i)?i:s||(r.git_user_name||r.git_user_email?{...r,identity_source:"git_config"}:o||i||{git_user_name:null,git_user_email:null,platform_login:null,identity_source:"git_config"})}async function Ne(e){let{gitRoot:t,installationStorePath:n,forceResend:r}=e,o=e.exec??C,s=e.env??process.env,i=await ui(t,o,s),a=ti(i.git_user_name,i.git_user_email,i.identity_source,i.platform_login),u=(n?st(n):void 0)?.operator_identity_hash;if(!(r||u!==void 0&&u!==a||!u))return{commit:()=>{}};let p=n;return{operator:i,commit:()=>{p&&On(p,a,Ae())}}}function At(e){return e?!st(e)?.operator_identity_hash:!0}function dr(e){return!0}import{existsSync as Pi,readFileSync as Ni}from"node:fs";import{homedir as Or}from"node:os";import{join as P}from"node:path";import{basename as wi,join as re}from"node:path";import{existsSync as fr,readdirSync as di}from"node:fs";import{basename as fi,dirname as pi,relative as mi}from"node:path";var Me=class{constructor(t){this.home=t}components=[];truncated=!1;pluginExpandRemaining;homeRel(t){let n=mi(this.home,t).replace(/\\/g,"/");if(!n||n.startsWith("..")){let r=pi(t);return`external/${I(r)}/${fi(t)}`}return n}get atGlobalCap(){return this.truncated||this.components.length>=X}get pluginBudgetSpent(){return this.pluginExpandRemaining!==void 0&&this.pluginExpandRemaining<=0}readEntries(t){if(!fr(t))return[];try{return di(t,{withFileTypes:!0})}catch{return[]}}readJson(t,n){if(fr(t))return ne(t,n)}push(t){return this.components.length>=X?(this.truncated=!0,!1):this.pluginExpandRemaining!==void 0&&this.pluginExpandRemaining<=0?!1:(this.pluginExpandRemaining!==void 0&&(this.pluginExpandRemaining-=1),this.components.push(t),!0)}withPluginExpandCap(t,n){let r=this.pluginExpandRemaining;this.pluginExpandRemaining=t;try{let o=n(),s=t-(this.pluginExpandRemaining??0);return{result:o,expanded:s}}finally{this.pluginExpandRemaining=r}}};import{existsSync as Tt,readFileSync as gi,statSync as hi}from"node:fs";import{basename as mr,join as ge,relative as gr}from"node:path";var Ot=2e4,_i=4;function Si(e){return e.length<=Ot?e:`${e.slice(0,Ot-1)}\u2026`}function Ei(e){try{let t=gi(e),n=t.toString("utf8");return{hash:I(t),length:t.length,text:Si(n)}}catch{return null}}var pr={HOOK:"EVENT",COMMAND:"EXPLICIT_INVOCATION",MEMORY:void 0,MCP_SERVER:void 0,PLUGIN:void 0,SKILL:"UNSPECIFIED",RULE:"UNSPECIFIED",SUBAGENT:"UNSPECIFIED"};function yi(e){return e in pr?pr[e]:"UNSPECIFIED"}function Le(e,t){let n=Ei(t.absolutePath);if(!n)return!1;let r=t.name??mr(t.absolutePath).replace(/\.(md|mdc|toml)$/i,""),o={kind:t.kind,name:r,path:e.homeRel(t.absolutePath),text:n.text,content_hash:n.hash,content_length:n.length,origin:t.origin,enabled:t.enabled},s=yi(t.kind);return s&&(o.trigger=s),e.push(o)}function ki(e,t,n){let r=gr(e,t).replace(/\\/g,"/");return!r||r.startsWith("..")?mr(t).replace(/\.(md|mdc|toml)$/i,""):n?r.replace(/\.(md|mdc|toml)$/i,""):r}function Q(e,t){let{dir:n,kind:r,origin:o,enabled:s,nested:i,extensions:a}=t;vt(e,{walkRoot:n,currentDir:n,depth:0,kind:r,origin:o,enabled:s,nested:i,extensions:a})}function vt(e,t){let{walkRoot:n,currentDir:r,depth:o,kind:s,origin:i,enabled:a,nested:c,extensions:u}=t;if(!(o>_i))for(let l of e.readEntries(r)){if(e.atGlobalCap){e.truncated=!0;return}if(e.pluginBudgetSpent)return;if(c){if(!l.isDirectory())continue;let p=ge(r,l.name,c);if(Tt(p)){let _=gr(n,ge(r,l.name)).replace(/\\/g,"/");Le(e,{absolutePath:p,kind:s,origin:i,enabled:a,name:_||l.name});continue}vt(e,{walkRoot:n,currentDir:ge(r,l.name),depth:o+1,kind:s,origin:i,enabled:a,nested:c,extensions:u});continue}if(l.isDirectory()){vt(e,{walkRoot:n,currentDir:ge(r,l.name),depth:o+1,kind:s,origin:i,enabled:a,nested:c,extensions:u});continue}if(!l.isFile()||!u)continue;let f=l.name.toLowerCase();if(!u.some(p=>f.endsWith(p)))continue;let g=ge(r,l.name);Le(e,{absolutePath:g,kind:s,origin:i,enabled:a,name:ki(n,g,!0)})}}function hr(e){for(let t of e)if(Tt(t))try{if(hi(t).size>0)return t}catch{continue}return e.find(t=>Tt(t))}function Ii(e){if(e.prompt||e.type==="prompt")return"prompt";let t=e.command??e.bash??e.powershell??"";return/\bnpx\b/i.test(t)?"npx":/\.(sh|bash|zsh|js|mjs|cjs|ts|py)(\s|$|"|')/i.test(t)||/^(\.\/|~\/|\/|[A-Za-z]:[\\/])/.test(t.trim())?"script":"inline"}function Ri(e){return Array.isArray(e.hooks)&&e.hooks.length>0?e.hooks:[{type:e.type,command:e.command,bash:e.bash,powershell:e.powershell,prompt:e.prompt}]}function Ci(e,t,n,r){let o=e.homeRel(t);for(let[s,i]of Object.entries(n))if(!(!Array.isArray(i)||e.truncated))for(let a of i){if(!a||typeof a!="object"||e.truncated)continue;let c=a;for(let u of Ri(c)){if(e.truncated)return;let l=u.command??u.bash??u.prompt??u.powershell??c.powershell??"",f=Ii({type:u.type??c.type,command:u.command??c.command,bash:u.bash??c.bash,powershell:u.powershell??c.powershell,prompt:u.prompt??c.prompt}),g=typeof c.matcher=="string"?c.matcher:"",p=I(l),_=g?`${s}:${g}:${f}:${p}`:`${s}:${f}:${p}`,R=`${s}|${g}|${f}|${l}`;e.push({kind:"HOOK",name:_,path:o,content_hash:I(R),origin:r,enabled:!0,trigger:"EVENT",attributes:{event:s,...g?{matcher:g}:{},action_kind:f,action_hash:p}})}}}function he(e,t,n){let r=e.readJson(t,{});!r?.hooks||typeof r.hooks!="object"||Ci(e,t,r.hooks,n)}var _r={claude:{skillRoots:[".claude/skills"],dirs:[{dir:".claude/agents",kind:"SUBAGENT",extensions:[".md"]},{dir:".claude/commands",kind:"COMMAND",extensions:[".md"]}],memory:[".claude/CLAUDE.md"],hooks:[".claude/settings.json"],mcpJson:[".claude.json"],plugins:"claude"},cursor:{skillRoots:[".cursor/skills",".cursor/skills-cursor"],dirs:[{dir:".cursor/agents",kind:"SUBAGENT",extensions:[".md"]},{dir:".cursor/commands",kind:"COMMAND",extensions:[".md"]},{dir:".cursor/rules",kind:"RULE",extensions:[".mdc",".md"]}],memory:[".cursor/AGENTS.md"],hooks:[".cursor/hooks.json"],mcpJson:[".cursor/mcp.json"],plugins:"cursor"},codex:{skillRoots:[".agents/skills",".codex/skills"],dirs:[{dir:".codex/agents",kind:"SUBAGENT",extensions:[".toml",".md"]},{dir:".codex/prompts",kind:"COMMAND",extensions:[".md"]}],memory:[".codex/AGENTS.override.md",".codex/AGENTS.md"],hooks:[".codex/hooks.json"],mcpToml:[".codex/config.toml"]}};import{existsSync as xi,readFileSync as Ai}from"node:fs";function Ti(e){if(!e||typeof e!="object"||Array.isArray(e))return"unknown";let t=e;return typeof t.type=="string"&&t.type.length>0?t.type:typeof t.url=="string"?"http":typeof t.command=="string"?"stdio":"unknown"}function Sr(e,t,n){let o=e.readJson(t,{})?.mcpServers;if(!o||typeof o!="object")return;let s=e.homeRel(t);for(let[i,a]of Object.entries(o)){if(e.truncated)return;let c=Ti(a);e.push({kind:"MCP_SERVER",name:i,path:s,content_hash:I(`${i}|${c}`),origin:n,enabled:!0,attributes:{transport:c}})}}function Er(e,t,n){if(!xi(t))return;let r;try{r=Ai(t,"utf8")}catch{return}let o=e.homeRel(t),s=/^\[mcp_servers(?:\.(\w+)|\."([^"]+)"|\.'([^']+)')\]\s*$/gm,i;for(;(i=s.exec(r))!==null;){if(e.truncated)return;let a=i[1]??i[2]??i[3];if(!a)continue;let c=r.slice(i.index+i[0].length),u=c.search(/^\[/m),l=u===-1?c:c.slice(0,u),f="unknown";/^\s*url\s*=/m.test(l)?f="http":/^\s*command\s*=/m.test(l)&&(f="stdio"),e.push({kind:"MCP_SERVER",name:a,path:o,content_hash:I(`${a}|${f}`),origin:n,enabled:!0,attributes:{transport:f}})}}import{existsSync as Oi,readdirSync as vi}from"node:fs";import{join as A}from"node:path";var yr=50;function bt(e,t,n,r){if(!Oi(t))return{componentCount:0,expandTruncated:!1};let o=e.components.length,{expanded:s}=e.withPluginExpandCap(yr,()=>{Q(e,{dir:A(t,"skills"),kind:"SKILL",origin:n,enabled:r,nested:"SKILL.md"}),Q(e,{dir:A(t,"commands"),kind:"COMMAND",origin:n,enabled:r,extensions:[".md"]}),Q(e,{dir:A(t,"agents"),kind:"SUBAGENT",origin:n,enabled:r,extensions:[".md"]})});he(e,A(t,"hooks","hooks.json"),n),he(e,A(t,"hooks.json"),n);let i=e.components.length-o,a=s>=yr;return{componentCount:i,expandTruncated:a}}function wt(e,t){e.push({kind:"PLUGIN",name:t.pluginKey,path:t.rowPath,content_hash:t.contentHash,origin:"user",enabled:t.enabled,attributes:{...t.marketplace?{marketplace:t.marketplace}:{},...t.version?{version:t.version}:{},scope:t.scope,component_count:t.componentCount,...t.expandTruncated?{expand_truncated:!0}:{}}})}function kr(e){let t=A(e.home,".claude/plugins/installed_plugins.json"),n=e.readJson(t,{});if(!n)return;let r=n.plugins??{},s=e.readJson(A(e.home,".claude/settings.json"),{})?.enabledPlugins??{},i=e.homeRel(t);for(let[a,c]of Object.entries(r)){if(e.truncated)return;let u=Array.isArray(c)?c:[c],l=u[0]??{},f=s[a]===!0,g=a.includes("@")?a.split("@").slice(1).join("@"):"",p=typeof l.version=="string"?l.version:"",_=typeof l.scope=="string"?l.scope:"user",R=`plugin:${a}`,b=0,x=!1;for(let w of u)if(typeof w.installPath=="string"&&w.installPath.length>0){let W=bt(e,w.installPath,R,f);b+=W.componentCount,x=x||W.expandTruncated}wt(e,{pluginKey:a,rowPath:i,enabled:f,scope:_,version:p||void 0,marketplace:g||void 0,componentCount:b,expandTruncated:x,contentHash:I(`${a}|${p}|${_}|${f}|${b}`)})}}function bi(e){let t=e,n="";try{let r=vi(e,{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>o.name);if(r.length===1&&r[0])t=A(e,r[0]),n=r[0];else if(r.length>1){let o=[...r].sort(),s=o[o.length-1];s&&(t=A(e,s),n=s)}}catch{}return{installPath:t,version:n}}function Ir(e){let t=[{base:A(e.home,".cursor/plugins/local"),scope:"local"},{base:A(e.home,".cursor/plugins/cache"),scope:"cache"}];for(let{base:n,scope:r}of t)if(!e.truncated)for(let o of e.readEntries(n)){if(!o.isDirectory()||e.truncated)continue;if(r==="local"){let i=o.name,a=A(n,o.name),c=`plugin:${i}`,{componentCount:u,expandTruncated:l}=bt(e,a,c,!0);wt(e,{pluginKey:i,rowPath:e.homeRel(a),enabled:!0,scope:"local",componentCount:u,expandTruncated:l,contentHash:I(`${i}|local|${u}`)});continue}let s=o.name;for(let i of e.readEntries(A(n,s))){if(!i.isDirectory()||e.truncated)continue;let a=A(n,s,i.name),{installPath:c,version:u}=bi(a),l=`${i.name}@${s}`,f=`plugin:${l}`,{componentCount:g,expandTruncated:p}=bt(e,c,f,!0);wt(e,{pluginKey:l,rowPath:e.homeRel(c),enabled:!0,scope:"cache",version:u||void 0,marketplace:s,componentCount:g,expandTruncated:p,contentHash:I(`${l}|${u}|${g}`)})}}}function Ut(e,t){let n=_r[e],r=new Me(t),o="user";if(!n)return{components:[],truncated:!1};for(let i of n.skillRoots)Q(r,{dir:re(t,i),kind:"SKILL",origin:o,enabled:!0,nested:"SKILL.md"});for(let i of n.dirs)Q(r,{dir:re(t,i.dir),kind:i.kind,origin:o,enabled:!0,extensions:i.extensions});let s=hr(n.memory.map(i=>re(t,i)));s&&Le(r,{absolutePath:s,kind:"MEMORY",origin:o,enabled:!0,name:wi(s)});for(let i of n.hooks)he(r,re(t,i),o);for(let i of n.mcpJson??[])Sr(r,re(t,i),o);for(let i of n.mcpToml??[])Er(r,re(t,i),o);return n.plugins==="claude"?kr(r):n.plugins==="cursor"&&Ir(r),{components:r.components,truncated:r.truncated}}function Pt(e,t,n={}){let r=n.truncated===!0,o=Ct(e),s=new Set(e.map(l=>$(l.path,l.name)));if(n.forceFull===!0||t===void 0)return{hash:o,count:e.length,truncated:r,full:!0,upserts:e,removed:[],unchanged:!1};let a=[],c=t;for(let l of e){let f=$(l.path,l.name);c[f]!==l.content_hash&&a.push(l)}let u=[];if(!r){for(let l of Object.keys(c))if(!s.has(l)){let f=lr(l);f&&u.push(f)}}return{hash:o,count:e.length,truncated:r,full:!1,upserts:a,removed:u,unchanged:a.length===0&&u.length===0}}var Cr=3e5,Ui=new Set(["HOOK","MCP_SERVER","PLUGIN"]);function Nt(e,t,n){let r=new Set(t.map(s=>$(s.path,s.name))),o=[];for(let s of e)s.text!==void 0&&(n.has(s.content_hash)||r.has($(s.path,s.name))||o.push(s));return o}function Mt(e,t,n){let r=new Set(e);for(let s of t)r.add(s);let o=new Set(n.map(s=>s.content_hash));return[...r].filter(s=>o.has(s))}function Rr(e){return Buffer.byteLength(JSON.stringify(e),"utf8")}function xr(e){if(e.text===void 0)return e;let{text:t,...n}=e;return n}function Lt(e,t=Cr){let n=[],r=[];for(let l of e)Ui.has(l.kind)?n.push(l):r.push(l);r.sort((l,f)=>(l.text?.length??0)-(f.text?.length??0));let o=[...n,...r],s=[],i=2,a=0,c=0,u=[];for(let l of o){let f=s.length>0?1:0,g=Rr(l)+f;if(i+g<=t){s.push(l),i+=g,l.text!==void 0&&u.push(l.content_hash);continue}if(l.text!==void 0){let p=xr(l),_=Rr(p)+f;if(i+_<=t){s.push(p),i+=_,a+=1;continue}}c+=1}return{components:s,textDeferredCount:a,droppedCount:c,textHashesSent:u}}function Ht(e,t){return t.size===0?e:e.map(n=>n.text===void 0||!t.has(n.content_hash)?n:xr(n))}var Mi={claude:{skills:".claude/skills",subagents:".claude/agents",commands:".claude/commands",memory:".claude/CLAUDE.md",settings:".claude/settings.json"},cursor:{skills:[".cursor/skills",".cursor/skills-cursor"],subagents:".cursor/agents",commands:".cursor/commands",rules:".cursor/rules",mcp:".cursor/mcp.json"},codex:{skills:[".agents/skills",".codex/skills"],subagents:".codex/agents",commands:".codex/prompts",memory:".codex/AGENTS.md",settings:".codex/config.toml"}},Li=200,Ar=200,Hi=["allow","deny","ask"],Di=/(?<=^|[\s(,=:])(?:~|[A-Za-z]:)?[\\/][^\s,)]+/g,Dt="<path>",Fi=new RegExp(`${Dt}(?:\\s+[A-Za-z.][^\\s,)]*[\\\\/][^\\s,)]*)+`,"g");function ji(e){let t=e.replace(Di,Dt).replace(Fi,Dt);return t.length>Ar?`${t.slice(0,Ar)}...`:t}function Tr(e){let t=ne(e,{}),n=[];for(let r of Hi)for(let o of t.permissions?.[r]??[])typeof o=="string"&&o.length>0&&n.push({key:ji(o),mode:r});return{model:t.model??"",permissionKeys:n}}var Bi=10,$i=840*60*1e3,Gi="self-config-cache.json";function Ft(){return E("EV_AI_HOOK_USER_SPEC")?.toLowerCase()==="off"}function Ki(e,t=Date.now()){return e===void 0||!Number.isFinite(e)?!0:t-e>=$i}var Ji={claude:["claude"],cursor:["agent","cursor-agent"],codex:["codex"]};async function Vi(e,t=C){let n=Ji[e];if(!n||n.length===0)return null;let r=async o=>{let s=n[o];if(s===void 0)return null;let a=((await t(s,["--version"],2e3)).split(`
|
|
17
|
-
`)
|
|
18
|
-
`);return I(n)}function He(e,t,n=!1){let r=zi(e),o=e.length;return t===r?n?{hash:r,count:o,truncated:n}:{hash:r,count:o}:n?{hash:r,count:o,entries:e,truncated:n}:{hash:r,count:o,entries:e}}function Yi(e){return Pi(e)?v(Ni(e,"utf8"),{}):{}}function Xi(e,t){try{z(e,`${JSON.stringify(t)}
|
|
19
|
-
`)}catch(n){let r=n instanceof Error?n.message:String(n);d(`WARN: self-config cache write failed open: ${r}`)}}function qi(e,t,n,r){let o={...e,send_count:n};for(let s of Object.keys(t)){let i=t[s];i.entries!==void 0&&(o[s]=i.hash)}return r&&(o.user_spec_collected_at_ms=r.collectedAtMs,r.included&&(o.user_spec=r.hash,o.user_spec_components=r.componentHashes),o.user_spec_text_hashes=r.textHashes),o}async function vr(e,t=process.cwd(),n=Or(),r={}){let o=e==="claude",s=r.gitRoot??t,i=await Vi(e),a="",c=[];if(o){let U=Tr(P(n,".claude/settings.json")),L=Tr(P(t,".claude/settings.local.json"));a=L.model||U.model,c=[...U.permissionKeys,...L.permissionKeys].slice(0,Li)}let u=Mi[e]??{},l={present:!1,size:0},f=U=>{let L=Array.isArray(U)?U:U?[U]:[],y=[],K=!1;for(let Je of L){let O=de(P(n,Je));if(y=y.concat(O.entries),K=K||O.truncated,y.length>=X){y=y.slice(0,X),K=!0;break}}return{entries:y,truncated:K}},g=Wi(n),p=Yi(g),_=p[e]??{},R=(_.send_count??0)+1,b=R>0&&R%Bi===0,x=U=>b?void 0:_[U],w=f(u.skills),W=u.subagents?de(P(n,u.subagents)):{entries:[],truncated:!1},Ke=u.commands?de(P(n,u.commands)):{entries:[],truncated:!1},Vt=u.rules?de(P(n,u.rules)):{entries:[],truncated:!1},ie={skills:He(w.entries,x("skills"),w.truncated),subagents:He(W.entries,x("subagents"),W.truncated),commands:He(Ke.entries,x("commands"),Ke.truncated),rules:He(Vt.entries,x("rules"),Vt.truncated)},T={runner_platform:e,config_scope:"user",cli_version:i,claude_version:o?i:null,model:o&&a||null,permission_keys:c,user_scope:{skills:ie.skills,subagents:ie.subagents,commands:ie.commands,rules:ie.rules,memory:u.memory?fe(P(n,u.memory)):l,settings:u.settings?fe(P(n,u.settings)):l,mcp:u.mcp?fe(P(n,u.mcp)):l},local_settings:o?fe(P(t,".claude/settings.local.json")):l},Wt=null,zt=()=>{},Yt=r.nowMs??Date.now();if(!Ft()&&Ki(_.user_spec_collected_at_ms,Yt)){let U=_.user_spec_collected_at_ms!==void 0,L=Ut(e,n),y=Pt(L.components,_.user_spec_components,{forceFull:!_.user_spec_components,truncated:L.truncated}),K=new Set(_.user_spec_text_hashes??[]),Je=Nt(L.components,y.upserts,K),O=Lt(Ht([...y.upserts,...Je],K));T.user_spec_hash=y.hash,T.user_spec_count=y.count,T.user_spec_truncated=y.truncated||O.droppedCount>0,(O.components.length>0||y.removed.length>0||y.full)&&(y.full&&(T.user_spec_full=!0),O.components.length>0&&(T.user_spec=O.components),y.removed.length>0&&!T.user_spec_truncated&&(T.user_spec_removed=y.removed),O.textDeferredCount>0&&(T.user_spec_text_deferred=O.textDeferredCount));let Ve=y.full?{}:{..._.user_spec_components??{}};if(!T.user_spec_truncated)for(let te of y.removed)delete Ve[$(te.path,te.name)];for(let te of O.components)Ve[$(te.path,te.name)]=te.content_hash;Wt={hash:y.hash,componentHashes:Ve,textHashes:Mt(K,O.textHashesSent,L.components),included:O.components.length>0||y.removed.length>0&&!T.user_spec_truncated||y.full,collectedAtMs:Yt};let We=await Ne({gitRoot:s,installationStorePath:r.installationStorePath,forceResend:U});We.operator&&(T.operator=We.operator),zt=We.commit}let so=qi(_,ie,R,Wt);return{config:T,commit:()=>{p[e]=so,Xi(g,p),zt()}}}function oe(e,t,n){let r={installation_id:n.installationId};return n.platformAgentId&&(r.platform_agent_id=n.platformAgentId),n.sessionId&&(r.session_id=n.sessionId),n.turnId&&(r.turn_id=n.turnId),{schema_version:2,event:e,timestamp:Ae(),session_id:n.sessionId||null,turn_id:n.turnId||null,installation_id:n.installationId,platform:n.runnerPlatform,platform_agent_id:n.platformAgentId||null,runner_event:n.runnerEvent||null,agent_hook_version:H,host_arch:process.arch,node_version:process.version,correlation:r,payload:t}}import{existsSync as Kr}from"node:fs";import{spawn as Jr}from"node:child_process";import{basename as Ia}from"node:path";import{fileURLToPath as Ra}from"node:url";var br=/(?:^|\/|[\s"'=(])(?:\.cursor\/|\.claude\/|\.agents\/)skills(?:-cursor)?\/([^/]+)\/SKILL\.md/i,wr=/(?:^|\/|[\s"'=(])\.codex\/commands\/([^/]+)\.md\b/i,Zi=/(?:^|\s)\/([a-z][a-z0-9-]{1,63})\b/gi,Qi=new Set(["applications","app","bin","boot","data","dev","etc","home","lib","media","mnt","node_modules","opt","pkg","private","proc","projects","repos","run","sbin","src","srv","sys","tmp","usr","users","var","volumes","workspace","workspaces"]),ea=new Set(["read","read_file","view"]),ta=new Set(["bash","shell","zsh"]);function na(e){let t=e.replace(/\\/g,"/");return br.exec(t)?.[1]??null}function ra(e){let t=e.replace(/\\/g,"/"),r=wr.exec(t)?.[1];return r?r.toLowerCase():null}function oa(e){return na(e)??ra(e)}function sa(e){for(let t of["path","file_path","target_file"]){let n=e[t];if(typeof n=="string"&&n.length>0)return n}return null}function Ur(e){if(typeof e=="string")try{let t=JSON.parse(e);return Ur(t)}catch{return null}return!e||typeof e!="object"?null:sa(e)}function ia(e){if(!e||typeof e!="object")return null;let t=e.command;return typeof t=="string"&&t.length>0?t:null}function aa(e){let t=e.replace(/\\/g,"/"),n=br.exec(t);if(n?.[1])return n[1];let o=wr.exec(t)?.[1];return o?o.toLowerCase():null}function ca(e){return typeof e.tool_name=="string"?e.tool_name:typeof e.tool=="string"?e.tool:""}function Pr(e){let t=ca(e).toLowerCase();if(ea.has(t)){let n=Ur(e.tool_input);return n?oa(n):null}if(ta.has(t)){let n=ia(e.tool_input);return n?aa(n):null}return null}function la(e){let t=new Set,n=[];for(let r of e.matchAll(Zi)){let o=r[1]?.toLowerCase();!o||t.has(o)||Qi.has(o)||(t.add(o),n.push(o))}return n}function ua(e){return ue(e.prompt)}function Nr(e){let t=m(e,"command_name");if(t){let r=m(e,"expansion_type");if(r&&r!=="slash_command")return[];let o=t.replace(/^\//,"").toLowerCase();return o?[o]:[]}let n=ua(e);return n?la(n):[]}function jt(e){return e!==void 0&&on.includes(e)}function De(e,t){let n=e[t+1];return n&&!n.startsWith("--")?{value:n,next:t+1}:{next:t}}function Fe(e){let t,n,r,o,s;for(let i=0;i<e.length;i++){let a=e[i];if(a!==void 0){if(a==="--runner"){let c=De(e,i);t=c.value,i=c.next;continue}if(a.startsWith("--runner=")){t=a.slice(9);continue}if(a==="--url"){let c=De(e,i);c.value&&(r=c.value),i=c.next;continue}if(a.startsWith("--url=")){r=a.slice(6);continue}if(a==="--token"){let c=De(e,i);c.value&&(o=c.value),i=c.next;continue}if(a.startsWith("--token=")){o=a.slice(8);continue}if(a==="--base-url"){let c=De(e,i);c.value&&(s=c.value),i=c.next;continue}if(a.startsWith("--base-url=")){s=a.slice(11);continue}!a.startsWith("-")&&n===void 0&&(n=a)}}return{runner:jt(t)?t:void 0,event:n,collectorUrl:r,orgToken:o,baseUrl:s}}function Bt(e){let t=e.collectorUrl?.trim(),n;if(t)n=t;else{let o=e.orgToken?.trim();o&&(n=Ie(o,e.baseUrl?.trim()??void 0))}if(!n)return;let r=ae(n);if(r){d(`WARN: ignoring --url/--token collector override: ${r}`);return}return ce(n)}function Mr(e,t){if(m(e,"conversation_id"))return!0;if(t==="")return!1;let n=t[0];return n?.toLowerCase()===n}function da(){return!!(E("CURSOR_VERSION")??E("CURSOR_PROJECT_DIR"))}function $t(e,t,n){return e!=="claude"&&e!=="codex"?!1:Mr(t,n)?!0:da()}function Gt(e,t,n,r){if(Mr(e,t))return"cursor";if(jt(r))return r;let o=m(e,"conversation_id"),s=m(e,"turn_id"),i=m(e,"session_id"),a=t.toLowerCase(),c="unknown";return o||t===a&&t!==""?c="cursor":s?c="codex":(i||a==="sessionstart"||a==="sessionend"||a==="stop"||a==="stopfailure"||a==="pretooluse"||a==="posttooluse"||a==="posttoolusefailure"||a==="permissiondenied"||a==="subagentstart"||a==="subagentstop"||a==="userpromptexpansion")&&(c="claude"),jt(n)&&(c=n),c}function je(e,t){let n=e.toLowerCase();return n==="sessionend"||n==="stopfailure"||n==="subagentstop"?!0:n==="stop"&&t==="codex"}function fa(e){switch(e){case"sessionstart":return"session_start";case"stop":case"sessionend":case"stopfailure":return"session_end";case"pretooluse":case"posttooluse":case"posttoolusefailure":case"permissiondenied":case"beforemcpexecution":case"beforeshellexecution":case"afterfileedit":case"subagentstart":case"subagentstop":return"tool_invoked";case"beforesubmitprompt":case"userpromptexpansion":case"userpromptsubmit":return"skill_invoked";default:return""}}function Lr(e){let t=e.toLowerCase();return t==="posttooluse"?!0:t==="posttoolusefailure"||t==="permissiondenied"?!1:null}function Hr(e,t,n){let r=m(e,"session_id")||m(e,"conversation_id"),o=m(e,"prompt.id")||m(e,"prompt_id")||m(e,"generation_id")||m(e,"turn_id"),s=m(e,"hook_event_name")||m(e,"event"),i=m(e,"source"),a=Gt(e,s,t,n);return{sessionId:r,turnId:o,runnerEvent:s,hookSource:i,runnerPlatform:a}}var pa=["session_start","session_end","tool_invoked","skill_invoked"];function ma(e){return pa.includes(e)}function Dr(e,t){return e&&ma(e)?e:fa(t.toLowerCase())}function Fr(e){let t=m(e,"tool_name")||m(e,"tool")||null,n=e.tool_input,o=(n&&typeof n=="object"?ue(n.skill)||ue(n.skill_name):"")||m(e,"skill_name")||null;return o??=Pr(e),{toolName:t,skillName:o}}var ga=/^[A-Za-z][A-Za-z0-9_.:-]{0,63}$/;function jr(e){for(let t of["subagent_type","agent_type"]){let n=m(e,t);if(n&&ga.test(n))return n}return null}function Br(e){let t=Y(e,"duration_ms");if(typeof t=="number")return t;let n=Y(e,"duration");return typeof n=="number"?n:null}var ha="error",_a="interrupted",Sa="permission_denied",Ea=/^[A-Za-z][A-Za-z0-9_.-]{0,63}$/;function Kt(e){return Ea.test(e)?e:null}function ya(e){for(let t of["failure_type","error_type"]){let n=Kt(m(e,t));if(n)return n}return null}function $r(e,t){return Y(e,"is_interrupt")===!0?_a:t.toLowerCase()==="permissiondenied"?Sa:ya(e)??ha}function ka(e,t){let n=null;for(let r of t)r&&(e===r||e.startsWith(`${r}_`)||e.startsWith(`${r}-`))&&(n===null||r.length>n.length)&&(n=r);return n}function Gr(e,t=[]){if(!e)return{mcpServer:null,mcpTool:null};let n=/^mcp__(.+?)__(.+)$/i.exec(e);if(n?.[1]&&n[2])return{mcpServer:n[1],mcpTool:n[2]};if(/^MCP:/i.test(e)){let r=e.slice(4);if(!r)return{mcpServer:null,mcpTool:null};let o=r.indexOf(":");return o>0?{mcpServer:r.slice(0,o),mcpTool:r.slice(o+1)||null}:{mcpServer:ka(r,t),mcpTool:r}}return{mcpServer:null,mcpTool:null}}var _e="__post",Be="__work";function Ca(e,t){let n=e.payload,r=n&&typeof n=="object"&&!Array.isArray(n)?Object.keys(n):[],o=e.correlation&&typeof e.correlation=="object"?Object.keys(e.correlation):[];return JSON.stringify({event:e.event,schema_version:e.schema_version,agent_hook_version:e.agent_hook_version,host_arch:e.host_arch,node_version:e.node_version,build_ms:e.build_ms,body_bytes:t,correlation_keys:o,payload_keys:r})}function Vr(e){switch(e){case"session_start":return Zt;case"session_end":return Qt;case"tool_invoked":case"skill_invoked":return Xe;default:return Xe}}function xa(e,t,n){return`${JSON.stringify({url:e,timeoutMs:t})}
|
|
20
|
-
|
|
21
|
-
`)
|
|
22
|
-
|
|
23
|
-
`)
|
|
15
|
+
npx ${Le} install`)}function Er(e){return typeof e!="string"?!1:e.includes("@ev-ai/agent-hook")||e.includes("agent-hook/dist/hook")||e.includes(".ev-ai/agent-hook")||e.includes(z)||/(?:^|[\s/"'])ev-ai-agent-hook(?:$|[\s"'])/.test(e)}function vt(e,t){return`${e.replace(/\s+--runner(?:=|\s+)\S+/g,"").trimEnd()} --runner ${t}`}function X(e,t){xt(Tt(e),{recursive:!0}),qs(e,`${JSON.stringify(t,null,2)}
|
|
16
|
+
`,"utf8")}function G(e){if(B(e))try{return JSON.parse(Ys(e,"utf8"))}catch(t){throw t instanceof SyntaxError?new Error(`Invalid JSON in ${e} \u2014 fix or remove the file`,{cause:t}):t}}function hi(e,t){let n=rr(t.collectorUrl),r={...e,schema_version:e?.schema_version??n.schema_version};return t.collectorUrl!==void 0?r.collector_url=t.collectorUrl:r.collector_url=e?.collector_url??n.collector_url,delete r.repo_ingest_token,delete r.installation_id,r.mcp_servers??=n.mcp_servers,r}function Ei(e){return(e.schema_version??2)===2&&e.collector_url===void 0&&(e.mcp_servers?.length??0)===0&&e.platform_agent_id===void 0&&e.capture_hook_input===void 0&&e.repo_ingest_token===void 0}function Sr(e,t){let n=y(e,Ue),r=G(n),o=hi(r,t);return t.collectorUrl!==void 0||B(n)||!Ei(o)?(X(n,o),{manifestPath:n,wrote:!0}):{manifestPath:void 0,wrote:!1}}function At(e){if(e===null||typeof e!="object")return!1;let t=e,n=String(t.CLAUDE_CODE_ENABLE_TELEMETRY??"").toLowerCase();return n==="1"||n==="true"?!0:Object.keys(t).some(r=>r.startsWith("OTEL_"))}function Si(e=process.platform){switch(e){case"darwin":return"/Library/Application Support/ClaudeCode";case"win32":return y(process.env.ProgramFiles??"C:\\Program Files","ClaudeCode");default:return"/etc/claude-code"}}function yi(e=process.platform){let t=Si(e),n=[y(t,"managed-settings.json")],r=y(t,"managed-settings.d");try{if(!B(r))return n;let o=zs(r).filter(s=>s.endsWith(".json")&&!s.startsWith(".")).sort().map(s=>y(r,s));n.push(...o)}catch{}return n}function Ii(e){if(At(process.env))return!0;let t=j();return[...yi(),y(t,".claude","settings.json"),y(t,".claude","remote-settings.json"),y(e,".claude","settings.json"),y(e,".claude","settings.local.json")].some(r=>{try{let o=G(r);return o?At(o.env):!1}catch{return!1}})}function Ri(e){try{let t=G(y(e,".claude","settings.json"));return t?At(t.env):!1}catch{return!1}}function yr(e){return Array.isArray(e)?e:[]}function Ge(e){let t=[],n=r=>!!r&&typeof r=="object"&&Er(r.command);for(let r of yr(e)){if(!r||typeof r!="object"){t.push(r);continue}let o=Array.isArray(r.hooks)?r.hooks:[],s=o.filter(a=>!n(a));if(!(s.length===0&&o.some(n))){if(s.length!==o.length){t.push({...r,hooks:s});continue}t.push(r)}}return t}function Ir(e,t){return[...Ge(e),...t]}function bt(e){return Array.isArray(e)?e.filter(t=>!t||typeof t!="object"?!0:!Er(t.command)):[]}function ki(e,t){return[...bt(e),{command:t}]}function Ci(e){let t=()=>({hooks:[{type:"command",command:e}]});return{SessionStart:[t()],UserPromptExpansion:[t()],PreToolUse:[t()],PostToolUse:[t()],PostToolUseFailure:[t()],PermissionDenied:[t()],Stop:[t()],StopFailure:[t()],SessionEnd:[t()],SubagentStart:[t()],SubagentStop:[t()]}}function Oi(e){let t={type:"command",command:e,statusMessage:In},n=()=>({hooks:[t]});return{SessionStart:[n()],UserPromptSubmit:[n()],PreToolUse:[n()],PostToolUse:[n()],Stop:[n()]}}var Ai=["sessionStart","beforeSubmitPrompt","preToolUse","postToolUse","postToolUseFailure","beforeShellExecution","afterShellExecution","beforeReadFile","afterFileEdit","beforeMCPExecution","subagentStart","subagentStop","stop"],xi=[];function Ti(e,t=xi){let n={...e};for(let r of t){if(!(r in n))continue;let o=bt(n[r]);o.length===0?delete n[r]:n[r]=o}return n}function vi(e,t,n={}){let r=y(e,".claude/settings.json"),o=vt(t,"claude"),s=G(r)??{};if(Ii(e)&&!n.force){if(s.hooks&&typeof s.hooks=="object"){let u={...s.hooks};for(let f of Object.keys(u))u[f]=Ge(u[f]),yr(u[f]).length===0&&delete u[f];Object.keys(u).length===0?delete s.hooks:s.hooks=u,X(r,s)}return!1}let i=s.hooks&&typeof s.hooks=="object"?s.hooks:{},c=Ci(o),l={...i};for(let[u,f]of Object.entries(c))l[u]=Ir(i[u],f);return s.hooks=l,X(r,s),!0}function bi(e,t){let n=y(e,".cursor/hooks.json"),r=vt(t,"cursor"),o=G(n)??{},s=o.hooks&&typeof o.hooks=="object"?o.hooks:{},a=Ti({...s});for(let i of Ai)a[i]=ki(a[i],r);X(n,{...o,version:typeof o.version=="number"?o.version:1,hooks:a})}function wi(e,t){let n=y(e,".codex/hooks.json"),r=vt(t,"codex"),o=G(n)??{},s=o.hooks&&typeof o.hooks=="object"?o.hooks:{},a=Oi(r),i={...s};for(let[c,l]of Object.entries(a))i[c]=Ir(s[c],l);X(n,{...o,hooks:i})}function Pi(e){let t=y(e,".claude/settings.json"),n=G(t);if(!n?.hooks||typeof n.hooks!="object")return;let r={...n.hooks},o=!1;for(let s of Object.keys(r)){let a=r[s],i=Ge(a);JSON.stringify(a)!==JSON.stringify(i)&&(o=!0),i.length===0?delete r[s]:r[s]=i}o&&(Object.keys(r).length===0?delete n.hooks:n.hooks=r,X(t,n),d(`Removed ev-ai hooks from ${t}`))}function Ni(e){let t=y(e,".cursor/hooks.json"),n=G(t);if(!n?.hooks||typeof n.hooks!="object")return;let r={...n.hooks},o=!1,s=0;for(let a of Object.keys(r)){let i=r[a],c=bt(i);JSON.stringify(i)!==JSON.stringify(c)&&(o=!0),c.length===0?delete r[a]:(r[a]=c,s+=c.length)}if(o){if(s===0&&Object.keys(r).length===0&&Object.keys(n).filter(i=>i!=="hooks"&&i!=="version").length===0){Be(t,{force:!0}),d(`Removed ${t}`);return}X(t,{...n,hooks:r}),d(`Removed ev-ai hooks from ${t}`)}}function Ui(e){let t=y(e,".codex/hooks.json"),n=G(t);if(!n?.hooks||typeof n.hooks!="object")return;let r={...n.hooks},o=!1,s=0;for(let a of Object.keys(r)){let i=r[a],c=Ge(i);JSON.stringify(i)!==JSON.stringify(c)&&(o=!0),c.length===0?delete r[a]:(r[a]=c,s+=c.length)}if(o){if(s===0&&Object.keys(r).length===0&&Object.keys(n).filter(i=>i!=="hooks").length===0){Be(t,{force:!0}),d(`Removed ${t}`);return}X(t,{...n,hooks:r}),d(`Removed ev-ai hooks from ${t}`)}}function wt(e=process.platform,t=process.arch,n={}){if(e==="win32")throw new Error("Windows install is not supported yet. Use macOS/Linux, or wait for phase-2 native commands.");(n.requireBinaryArch??!0)&&or(e,t)}async function Rr(e={}){let t=oi(e);e.collectorUrl=t;let n=e.skipClaude===!0,r=e.skipCursor===!0,o=e.skipCodex===!0;if(n&&r&&o)throw new Error("at least one runner must be wired; refuse --no-claude --no-cursor --no-codex together");let s=e.delivery??fr();wt(process.platform,process.arch,{requireBinaryArch:s==="binary"});let a=e.cwd??process.cwd(),i=await $(a),{command:c,hookPath:l,strategy:u}=_i(i,j(),s),{installationId:f,storePath:g}=await Fe(i,{overrideId:e.installationId}),{manifestPath:m,wrote:_}=Sr(i,e),E=[];return n?d("Skipped Claude hook \u2014 --no-claude"):vi(i,c,{force:e.force})?(E.push("Claude"),e.force&&Ri(i)&&d("Forced Claude hook despite project native OTEL \u2014 expect duplicate session/tool events")):d("Skipped Claude hook \u2014 native OTEL telemetry already enabled (avoids duplicate events); pass --force to wire anyway"),r?d("Skipped Cursor hook \u2014 --no-cursor"):(bi(i,c),E.push("Cursor")),o?d("Skipped Codex hook \u2014 --no-codex"):(wi(i,c),E.push("Codex")),d(`Installed hook (${u}) at ${l}`),d(`Installation identity ${f} at ${g}`),_&&m?d(`Shared manifest written to ${m}`):d("Using package default collector config (no shared manifest file needed)"),d(E.length>0?`Wired ${E.join(", ")} hooks in ${i} (commands include --runner)`:`No runner hooks wired in ${i} (Claude skipped by OTEL; Cursor/Codex excluded via flags)`),u==="npx"?d("Hook commands use npx and may be committed; teammates need Node on PATH only (no install step, no env vars when collector_url is in the shared manifest)."):u==="project_binary"?d("Hook commands are git-root-relative and may be committed; each collaborator runs install once to populate .ev-ai/agent-hook/ (gitignored)."):u==="dev_mjs"&&d("Hook commands use node + monorepo packages/agent-hook/dist/hook.mjs (local delivery; rebuild with yarn workspace @ev-ai/agent-hook build)."),_&&m&&e.collectorUrl&&d("Shared manifest includes collector_url \u2014 commit it with hook configs so teammates post without env vars."),{gitRoot:i,hookPath:l,manifestPath:m,installationStorePath:g,strategy:u}}async function kr(e=process.cwd()){wt(process.platform,process.arch,{requireBinaryArch:!0});let t=await $(e),{projectPath:n,globalPath:r}=mi(t);d(`Refreshed ${r}`),d(`Refreshed ${n}`),d("Hook configs and shared manifest left unchanged")}async function Cr(e={}){let t=ri(e);e.collectorUrl=t,wt(process.platform,process.arch,{requireBinaryArch:!1});let n=e.cwd??process.cwd(),r=await $(n),{manifestPath:o,wrote:s}=Sr(r,e);if(t!==void 0&&(!o||!s))throw new Error("configure failed to write shared collector manifest");return s&&o?d(`Wrote ${o}`):t===void 0&&d("No --url given and no shared manifest yet \u2014 pass --url <\u2026/{orgToken}/hook> to write collector destination."),d("Manifest only \u2014 enable ev-ai marketplace plugins. Do not also run file-wiring install for the same events."),{gitRoot:r,manifestPath:o}}function Or(e){for(let t of[()=>Pi(e),()=>Ni(e),()=>Ui(e)])try{t()}catch(n){let r=n instanceof Error?n.message:String(n);d(`WARN: strip skipped a hook file: ${r}`)}}async function Ar(e=process.cwd()){let t=await $(e);return Or(t),d("Stripped ev-ai file-wired hooks; shared collector manifest left in place."),d("Next: enable ev-ai marketplace plugins, then restart runners."),{gitRoot:t}}async function xr(e=process.cwd()){let t=await $(e);Or(t);for(let n of $e){let r=y(t,n);if(B(r))try{Be(r,{force:!0}),d(`Removed ${r}`)}catch(o){let s=o instanceof Error?o.message:String(o);d(`WARN: uninstall could not remove ${r}: ${s}`)}}}import{createHash as ia}from"node:crypto";import{existsSync as aa,mkdirSync as ca,readdirSync as la,readFileSync as Br,unlinkSync as jr,writeFileSync as ua}from"node:fs";import{homedir as Gr}from"node:os";import{join as Ht}from"node:path";var Tr=/(?:^|\/|[\s"'=(])(?:\.cursor\/|\.claude\/|\.agents\/)skills(?:-cursor)?\/([^/]+)\/SKILL\.md/i,vr=/(?:^|\/|[\s"'=(])\.codex\/commands\/([^/]+)\.md\b/i,Li=/(?:^|\s)\/([a-z][a-z0-9-]{1,63})\b/gi,Mi=new Set(["applications","app","bin","boot","data","dev","etc","home","lib","media","mnt","node_modules","opt","pkg","private","proc","projects","repos","run","sbin","src","srv","sys","tmp","usr","users","var","volumes","workspace","workspaces"]),Hi=new Set(["read","read_file","view"]),Di=new Set(["bash","shell","zsh"]);function Fi(e){let t=e.replace(/\\/g,"/");return Tr.exec(t)?.[1]??null}function $i(e){let t=e.replace(/\\/g,"/"),r=vr.exec(t)?.[1];return r?r.toLowerCase():null}function Pt(e){return Fi(e)??$i(e)}function Bi(e){for(let t of["path","file_path","target_file"]){let n=e[t];if(typeof n=="string"&&n.length>0)return n}return null}function Ke(e){if(typeof e=="string")try{let t=JSON.parse(e);return Ke(t)}catch{return null}return!e||typeof e!="object"?null:Bi(e)}function ji(e){if(!e||typeof e!="object")return null;let t=e.command;return typeof t=="string"&&t.length>0?t:null}function Gi(e){let t=e.replace(/\\/g,"/"),n=Tr.exec(t);if(n?.[1])return n[1];let o=vr.exec(t)?.[1];return o?o.toLowerCase():null}function Ki(e){return typeof e.tool_name=="string"?e.tool_name:typeof e.tool=="string"?e.tool:""}function br(e){let t=Ki(e).toLowerCase();if(Hi.has(t)){let n=Ke(e.tool_input)??ee(e.file_path),r=n?Pt(n):null;if(r)return r}if(Di.has(t)){let n=ji(e.tool_input)??ee(e.command);return n?Gi(n):null}return null}function Ji(e){let t=new Set,n=[];for(let r of e.matchAll(Li)){let o=r[1]?.toLowerCase();!o||t.has(o)||Mi.has(o)||(t.add(o),n.push(o))}return n}function Vi(e){return ee(e.prompt)}function wr(e){let t=p(e,"command_name");if(t){let r=p(e,"expansion_type");if(r&&r!=="slash_command")return[];let o=t.replace(/^\//,"").toLowerCase();return o?[o]:[]}let n=Vi(e);return n?Ji(n):[]}function Nt(e){return e!==void 0&&Rn.includes(e)}function Je(e,t){let n=e[t+1];return n&&!n.startsWith("--")?{value:n,next:t+1}:{next:t}}function Ve(e){let t,n,r,o,s;for(let a=0;a<e.length;a++){let i=e[a];if(i!==void 0){if(i==="--runner"){let c=Je(e,a);t=c.value,a=c.next;continue}if(i.startsWith("--runner=")){t=i.slice(9);continue}if(i==="--url"){let c=Je(e,a);c.value&&(r=c.value),a=c.next;continue}if(i.startsWith("--url=")){r=i.slice(6);continue}if(i==="--token"){let c=Je(e,a);c.value&&(o=c.value),a=c.next;continue}if(i.startsWith("--token=")){o=i.slice(8);continue}if(i==="--base-url"){let c=Je(e,a);c.value&&(s=c.value),a=c.next;continue}if(i.startsWith("--base-url=")){s=i.slice(11);continue}!i.startsWith("-")&&n===void 0&&(n=i)}}return{runner:Nt(t)?t:void 0,event:n,collectorUrl:r,orgToken:o,baseUrl:s}}function Ut(e){let t=e.collectorUrl?.trim(),n;if(t)n=t;else{let o=e.orgToken?.trim();o&&(n=Ne(o,e.baseUrl?.trim()??void 0))}if(!n)return;let r=pe(n);if(r){d(`WARN: ignoring --url/--token collector override: ${r}`);return}return me(n)}function Pr(e,t){if(p(e,"conversation_id"))return!0;if(t==="")return!1;let n=t[0];return n?.toLowerCase()===n}function Wi(){return!!(k("CURSOR_VERSION")??k("CURSOR_PROJECT_DIR"))}function Lt(e,t,n){return e!=="claude"&&e!=="codex"?!1:Pr(t,n)?!0:Wi()}function Re(e,t,n,r){if(Pr(e,t))return"cursor";if(Nt(r))return r;let o=p(e,"conversation_id"),s=p(e,"turn_id"),a=p(e,"session_id"),i=t.toLowerCase(),c="unknown";return o||t===i&&t!==""?c="cursor":s?c="codex":(a||i==="sessionstart"||i==="sessionend"||i==="stop"||i==="stopfailure"||i==="pretooluse"||i==="posttooluse"||i==="posttoolusefailure"||i==="permissiondenied"||i==="subagentstart"||i==="subagentstop"||i==="userpromptexpansion")&&(c="claude"),Nt(n)&&(c=n),c}function We(e,t){let n=e.toLowerCase();return n==="sessionend"||n==="stopfailure"||n==="subagentstop"?!0:n==="stop"&&t==="codex"}function zi(e){switch(e){case"sessionstart":return"session_start";case"stop":case"sessionend":case"stopfailure":return"session_end";case"pretooluse":case"posttooluse":case"posttoolusefailure":case"permissiondenied":case"beforemcpexecution":case"beforeshellexecution":case"aftershellexecution":case"beforereadfile":case"afterfileedit":case"subagentstart":case"subagentstop":return"tool_invoked";case"beforesubmitprompt":case"userpromptexpansion":case"userpromptsubmit":return"skill_invoked";default:return""}}function Nr(e){let t=e.toLowerCase();return t==="posttooluse"?!0:t==="posttoolusefailure"||t==="permissiondenied"?!1:null}function Ur(e,t,n){let r=p(e,"session_id")||p(e,"conversation_id"),o=p(e,"prompt.id")||p(e,"prompt_id")||p(e,"generation_id")||p(e,"turn_id"),s=p(e,"hook_event_name")||p(e,"event"),a=p(e,"source"),i=Re(e,s,t,n);return{sessionId:r,turnId:o,runnerEvent:s,hookSource:a,runnerPlatform:i}}var Yi=["session_start","session_end","tool_invoked","skill_invoked"];function Xi(e){return Yi.includes(e)}function Lr(e,t){return e&&Xi(e)?e:zi(t.toLowerCase())}var qi={beforeshellexecution:"Shell",aftershellexecution:"Shell",beforereadfile:"Read",afterfileedit:"Write"};function Zi(e){return/^mcp__/i.test(e)||/^MCP:/i.test(e)}function Mr(e,t=""){let n=p(e,"tool_name")||p(e,"tool")||null,r=t.toLowerCase();n?r==="beforemcpexecution"&&!Zi(n)&&(n=`MCP:${n}`):n=qi[r]??null;let o=e.tool_input,a=(o&&typeof o=="object"?ee(o.skill)||ee(o.skill_name):"")||p(e,"skill_name")||null,i=n&&e.tool_name!==n&&e.tool!==n?{...e,tool_name:n}:e;return a??=br(i),{toolName:n,skillName:a}}var Qi=/^[A-Za-z][A-Za-z0-9_.:-]{0,63}$/;function Hr(e){for(let t of["subagent_type","agent_type"]){let n=p(e,t);if(n&&Qi.test(n))return n}return null}function Dr(e){let t=te(e,"duration_ms");if(typeof t=="number")return t;let n=te(e,"duration");return typeof n=="number"?n:null}var ea="error",ta="interrupted",na="permission_denied",ra=/^[A-Za-z][A-Za-z0-9_.-]{0,63}$/;function Mt(e){return ra.test(e)?e:null}function oa(e){for(let t of["failure_type","error_type"]){let n=Mt(p(e,t));if(n)return n}return null}function Fr(e,t){return te(e,"is_interrupt")===!0?ta:t.toLowerCase()==="permissiondenied"?na:oa(e)??ea}function sa(e,t){let n=null;for(let r of t)r&&(e===r||e.startsWith(`${r}_`)||e.startsWith(`${r}-`))&&(n===null||r.length>n.length)&&(n=r);return n}function $r(e,t=[]){if(!e)return{mcpServer:null,mcpTool:null};let n=/^mcp__(.+?)__(.+)$/i.exec(e);if(n?.[1]&&n[2])return{mcpServer:n[1],mcpTool:n[2]};if(/^MCP:/i.test(e)){let r=e.slice(4);if(!r)return{mcpServer:null,mcpTool:null};let o=r.indexOf(":");return o>0?{mcpServer:r.slice(0,o),mcpTool:r.slice(o+1)||null}:{mcpServer:sa(r,t),mcpTool:r}}return{mcpServer:null,mcpTool:null}}var Kr=3e4,da="claims",fa=!0,pa=100,ma=new Set(["sessionstart","sessionend","stopfailure"]),ga=["tool_name","tool","command","file_path","url"];function _a(e=Gr()){return Ht(Ie(e),da)}function Jr(e){let t=e.split(`
|
|
17
|
+
`,1)[0]??"";return Number(t.trim())}function Vr(e){return ia("sha256").update(e).digest("hex").slice(0,32)}function ha(e){let t=[];for(let n of ga){let r=p(e,n).trim();r&&t.push(`${n}=${r}`)}return t.length===0?"":Vr(t.join("\0"))}function Ea(e){let t=e.sessionId.trim();if(!t)return;let n=e.runnerEvent.trim().toLowerCase(),r=e.turnId.trim(),o=e.toolUseId.trim(),s=e.subagentId?.trim()??"",a=e.callFingerprint?.trim()??"",i=!!(o||r||s),c=ma.has(n);if(!i&&!c)return;let l=e.runnerPlatform.trim()||"unknown";return Vr(`${l}|${t}|${n}|${r}|${o}|${a}|${s}`)}function Sa(e){return e instanceof Error&&"code"in e&&e.code==="EEXIST"}function ya(e,t){return Ht(e,t)}function Ia(e,t=Date.now()){let n;try{n=la(e)}catch{return}let r=0;for(let o of n){if(r>=pa)break;r+=1;let s=Ht(e,o),a=Number.NaN;try{a=Jr(Br(s,"utf8"))}catch{continue}let i=t-a;if(!(!Number.isFinite(i)||i<0||i<Kr))try{jr(s)}catch{}}}function Ra(e,t,n=Date.now()){let r=ya(t,e);try{if(aa(r)){let o=Number.NaN;try{o=Jr(Br(r,"utf8"))}catch{}let s=n-o;if(Number.isFinite(s)&&s>=0&&s<Kr)return!1;try{jr(r)}catch{}}}catch{}try{ca(t,{recursive:!0}),ua(r,`${n}
|
|
18
|
+
`,{encoding:"utf8",flag:"wx"})}catch(o){if(Sa(o))return!1;let s=o instanceof Error?o.message:String(o);return d(`WARN: event claim failed open: ${s}`),!0}return Ia(t,n),!0}function ka(e,t,n){let r=p(e,"session_id")||p(e,"conversation_id"),o=p(e,"prompt.id")||p(e,"prompt_id")||p(e,"generation_id")||p(e,"turn_id"),s=p(e,"tool_use_id"),a=p(e,"subagent_id")||p(e,"agent_id"),i=Re(e,t,void 0,n),c=ha(e);return{runnerPlatform:i,sessionId:r,runnerEvent:t,turnId:o,toolUseId:s,subagentId:a,callFingerprint:c}}function Wr(e,t,n,r=Gr(),o=Date.now()){if(!fa)return!0;let s=Ea(ka(e,t,n));if(!s)return!0;let a=Ra(s,_a(r),o);return!a&&k("EV_AI_HOOK_DEBUG")&&d(`DEBUG: duplicate hook event suppressed (claim ${s.slice(0,8)}\u2026)`),a}var Dt={claude:".claude",cursor:".cursor",codex:".codex",opencode:".opencode"};function ke(e){let n=e.replace(/^\/+|\/+$/g,"").toLowerCase().split("/").filter(Boolean);return n.length<2?"":n.join("/")}function Ca(e){if(!e)return"";let t=e.replace(/^([a-z]+:\/\/)[^/@]+@/i,"$1");t=t.replace(/\.git$/i,"");let n=t.match(/^git@[^:]+:(.+)$/);if(n?.[1])return ke(n[1]);let r=t.match(/^ssh:\/\/[^/]+\/(.+)$/i);if(r?.[1])return ke(r[1]);t=t.replace(/^https:\/\//i,""),t=t.replace(/^http:\/\//i,""),t=t.replace(/^ssh:\/\//i,"");let o=t.match(/^[^/]+\/(.+)$/);return o?.[1]?ke(o[1]):ke(t)}async function Ce(e=process.cwd()){let t=await U("git",["rev-parse","--is-inside-work-tree"],2e3,{cwd:e});if(!t.ok||t.stdout!=="true")return null;let[n,r,o,s]=await Promise.all([U("git",["remote","get-url","origin"],2e3,{cwd:e}),U("git",["branch","--show-current"],2e3,{cwd:e}),U("git",["rev-parse","HEAD"],2e3,{cwd:e}),U("git",["status","--porcelain"],2e3,{cwd:e})]),a=n.ok?n.stdout:null;return{remote:a===null?null:a.replace(/^([a-z]+:\/\/)[^/@]+@/i,"$1"),branch:r.ok?r.stdout:null,head:o.ok?o.stdout:null,dirty:s.ok?s.stdout.length>0:null}}async function zr(e,t,n,r=process.cwd(),o,s,a){if(t)return t;let i=Dt[n];if(!i)return"";let c=Kn(n,e.scope_path,a);if(s){let _=Zn(s,c);if(_)return _}let l=o??await Ce(r),u=l?.remote?Ca(l.remote):"";if(u||(u=ke(process.env.GITHUB_REPOSITORY??"")),!u)return"";let f=e.scope_path??"",g=f?`${f}/`:"",m=`${u}:${g}${i}`;return s&&Qn(s,c,m),m}var q=Vo(qr(),1);import{existsSync as Ua,readFileSync as La}from"node:fs";import{homedir as Zr}from"node:os";import{join as Ma}from"node:path";var Ha="cloud-cache.json",Da=1440*60*1e3,Fa=900*1e3;function $a(e=Zr()){return Ma(Ie(e),Ha)}function Ba(e){if(!Ua(e))return;let t=w(La(e,"utf8"),{});if(!(typeof t.context!="string"||typeof t.probed_at!="number"||t.result!==null&&t.result!==void 0&&typeof t.result!="object"))return{context:t.context,probed_at:t.probed_at,result:t.result??null}}function ja(e,t){try{Y(e,`${JSON.stringify(t)}
|
|
19
|
+
`)}catch(n){let r=n instanceof Error?n.message:String(n);d(`WARN: cloud cache write failed open: ${r}`)}}function Ga(e,t,n){if(!e||e.context!==t)return!1;let r=e.result===null?Fa:Da;return n-e.probed_at<r}async function Ka(e){let t=await fetch("http://169.254.169.254/latest/api/token",{method:"PUT",headers:{"X-aws-ec2-metadata-token-ttl-seconds":"60"},signal:AbortSignal.timeout(e)}).catch(()=>{});if(!t?.ok)return;let n=(await t.text()).trim();if(!n)return;let r={"X-aws-ec2-metadata-token":n},[o,s]=await Promise.all([fetch("http://169.254.169.254/latest/meta-data/placement/region",{headers:r,signal:AbortSignal.timeout(e)}).catch(()=>{}),fetch("http://169.254.169.254/latest/meta-data/instance-id",{headers:r,signal:AbortSignal.timeout(e)}).catch(()=>{})]);if(!o?.ok&&!s?.ok)return;let a=o?.ok?(await o.text()).trim():"",i=s?.ok?(await s.text()).trim():"";if(!(!a&&!i))return{provider:"aws",region:a,instance_id:i}}async function Ja(e){let t=await fetch("http://metadata.google.internal/computeMetadata/v1/instance/?recursive=true",{headers:{"Metadata-Flavor":"Google"},signal:AbortSignal.timeout(e)}).catch(()=>{});if(!t?.ok)return;let n=await t.json(),r=typeof n.zone=="string"?n.zone.split("/").pop()??"":"",o=n.id===void 0?"":String(n.id);if(!(!r&&!o))return{provider:"gcp",region:r,instance_id:o}}async function Va(e){let t=await fetch("http://169.254.169.254/metadata/instance?api-version=2021-02-01",{headers:{Metadata:"true"},signal:AbortSignal.timeout(e)}).catch(()=>{});if(!t?.ok)return;let n=await t.json(),r=n.compute?.location??"",o=n.compute?.vmId??"";if(!(!r&&!o))return{provider:"azure",region:r,instance_id:o}}async function Wa(e){let t=await Promise.allSettled([Ka(e),Ja(e),Va(e)]);for(let n of t)if(n.status==="fulfilled"&&n.value)return n.value;return null}async function Ft(e,t){if(e==="interactive")return null;let n=t?.home??Zr(),r=t?.timeoutMs??1e3,o=t?.nowMs??Date.now(),s=$a(n),a=Ba(s);if(Ga(a,e,o))return a.result;let i=await Wa(r);return ja(s,{context:e,probed_at:o,result:i}),i}import{existsSync as za}from"node:fs";import{homedir as Ya}from"node:os";import{join as $t}from"node:path";function Bt(e,t,n){if(!za(e))return;let r=ae(e,{});for(let o of Object.keys(r.mcpServers??{}))n.set(o,{name:o,source:t})}async function jt(e,t=process.cwd(),n="claude",r=Ya()){let o=new Map;for(let s of e.mcp_servers??[])s.name&&o.set(s.name,{name:s.name,source:"manifest"});return n==="claude"&&Bt($t(r,".claude.json"),"claude_json_user",o),Bt($t(t,".mcp.json"),"mcp_json",o),Bt($t(t,".cursor/mcp.json"),"cursor_mcp",o),[...o.values()]}var Xa=["CI","GITHUB_ACTIONS","GITLAB_CI","CIRCLECI","BUILDKITE","TF_BUILD","JENKINS_URL","JENKINS_HOME","CODEBUILD_BUILD_ID","DRONE","DRONE_BUILD_NUMBER","TEAMCITY_VERSION","TRAVIS","APPVEYOR","BITBUCKET_BUILD_NUMBER","KUBERNETES_SERVICE_HOST","REMOTE_CONTAINERS","DEVCONTAINER","GITHUB_REPOSITORY","GITHUB_REPOSITORY_ID","GITHUB_REF","GITHUB_SHA","GITHUB_RUN_ID","GITHUB_WORKFLOW","GITHUB_ACTOR","GITHUB_TRIGGERING_ACTOR","GITHUB_ACTOR_ID","GITHUB_USER","GITLAB_USER_LOGIN","GITLAB_USER_NAME","GITLAB_USER_EMAIL","BUILD_REQUESTEDFOR","BUILD_REQUESTEDFOREMAIL","BUILD_REQUESTEDFORID","BUILDKITE_BUILD_CREATOR","BUILDKITE_BUILD_CREATOR_EMAIL","BUILD_USER","BUILD_USER_ID","BUILD_USER_EMAIL","CHANGE_AUTHOR","CHANGE_AUTHOR_EMAIL","CIRCLE_USERNAME","CODEBUILD_INITIATOR","DRONE_COMMIT_AUTHOR","DRONE_COMMIT_AUTHOR_NAME","DRONE_COMMIT_AUTHOR_EMAIL","EV_AI_HOOK_OPERATOR_NAME","EV_AI_HOOK_OPERATOR_EMAIL","EV_AI_HOOK_OPERATOR_LOGIN","GIT_AUTHOR_NAME","GIT_AUTHOR_EMAIL","GIT_COMMITTER_NAME","GIT_COMMITTER_EMAIL","EMAIL","RUNNER_OS","RUNNER_ARCH","NODE_ENV","TERM_PROGRAM","CLAUDE_CODE_REMOTE","CLAUDE_CODE_REMOTE_SESSION_ID","CURSOR_AGENT","CURSOR_VERSION","CURSOR_CODE_REMOTE","CURSOR_USER_EMAIL","CODESPACES","CODESPACE_NAME","ANTHROPIC_BASE_URL","OPENAI_BASE_URL","OPENAI_API_BASE","AZURE_OPENAI_ENDPOINT","GOOGLE_GEMINI_BASE_URL","GEMINI_API_BASE","CLAUDE_CODE_USE_BEDROCK","CLAUDE_CODE_USE_VERTEX"],qa=["CURSOR_PROJECT_DIR"],Za=new Set(["key","api-key","api_key","apikey","token","sig","signature","access_token","password","pwd","secret","client_secret"]);function Qa(e){try{let t=new URL(e);(t.username||t.password)&&(t.username="",t.password="");for(let[n]of t.searchParams)Za.has(n.toLowerCase())&&t.searchParams.set(n,"[redacted]");return t.toString()}catch{return e}}function Gt(e=process.env){let t=Xa.map(r=>Object.prototype.hasOwnProperty.call(e,r)?{name:r,present:!0,value:Qa(e[r]??"")}:{name:r,present:!1}),n=qa.map(r=>({name:r,present:Object.prototype.hasOwnProperty.call(e,r)&&!!e[r]}));return[...t,...n]}import{createHash as ec}from"node:crypto";function O(e){return ec("sha256").update(e).digest("hex").slice(0,16)}function J(e,t){return`${e}\0${t}`}function Qr(e){let t=e.indexOf("\0");return t<=0?null:{path:e.slice(0,t),name:e.slice(t+1)}}function Kt(e){let n=[...e].sort((r,o)=>{let s=r.path.localeCompare(o.path);return s!==0?s:r.name.localeCompare(o.name)}).map(r=>`${r.path}|${r.name}|${r.content_hash}`).join(`
|
|
20
|
+
`);return O(n)}function tc(e,t,n="git_config",r=null){return O(`${e??""}|${t??""}|${r??""}|${n}`)}function nc(e){let t=null,n=null;for(let r of e.split(`
|
|
21
|
+
`)){let o=r.trim();if(!o)continue;let s=o.indexOf(" ");if(s<=0)continue;let a=o.slice(0,s).toLowerCase(),i=o.slice(s+1).trim();i&&(a==="user.name"?t=i:a==="user.email"&&(n=i))}return{git_user_name:t,git_user_email:n,platform_login:null}}async function rc(e,t=C){let n=await t("git",["config","--get-regexp","^user\\.(name|email)$"],2e3,{cwd:e});return nc(n)}function oc(e=process.env){let t=h(e.GIT_AUTHOR_NAME),n=h(e.GIT_AUTHOR_EMAIL);if(t||n)return{git_user_name:t,git_user_email:n,platform_login:null,identity_source:"git_env"};let r=h(e.GIT_COMMITTER_NAME),o=h(e.GIT_COMMITTER_EMAIL);if(r||o)return{git_user_name:r,git_user_email:o,platform_login:null,identity_source:"git_env"};let s=h(e.EMAIL);return s?{git_user_name:null,git_user_email:s,platform_login:null,identity_source:"git_env"}:null}async function sc(e,t=C){let n=await t("git",["log","-1","--format=%an%x00%ae"],2e3,{cwd:e});if(!n)return null;let r=n.indexOf("\0"),o=(r>=0?n.slice(0,r):n).trim(),s=(r>=0?n.slice(r+1):"").trim();return!o&&!s?null:{git_user_name:o||null,git_user_email:s||null,platform_login:null,identity_source:"git_log"}}function V(e,t,n,r=null){return!e&&!t&&!r?null:{git_user_name:e,git_user_email:t,platform_login:r,identity_source:n}}function ic(e=process.env){let t=V(h(e.EV_AI_HOOK_OPERATOR_NAME),h(e.EV_AI_HOOK_OPERATOR_EMAIL),"configured",h(e.EV_AI_HOOK_OPERATOR_LOGIN));if(t)return t;let n=h(e.GITHUB_ACTOR)??h(e.GITHUB_TRIGGERING_ACTOR)??h(e.GITHUB_USER),r=V(n,null,"github",n);if(r)return r;let o=h(e.GITLAB_USER_LOGIN),s=V(h(e.GITLAB_USER_NAME)??o,h(e.GITLAB_USER_EMAIL),"gitlab",o);if(s)return s;let a=V(h(e.BUILD_REQUESTEDFOR),h(e.BUILD_REQUESTEDFOREMAIL),"azure_devops",h(e.BUILD_REQUESTEDFORID));if(a)return a;let i=h(e.BUILDKITE_BUILD_CREATOR_EMAIL),c=V(h(e.BUILDKITE_BUILD_CREATOR),i,"buildkite",i);if(c)return c;let l=V(h(e.BUILD_USER)??h(e.CHANGE_AUTHOR),h(e.BUILD_USER_EMAIL)??h(e.CHANGE_AUTHOR_EMAIL),"jenkins",h(e.BUILD_USER_ID));if(l)return l;let u=h(e.CIRCLE_USERNAME),f=V(u,null,"circleci",u);if(f)return f;let g=h(e.CODEBUILD_INITIATOR),m=V(g,null,"codebuild",g);if(m)return m;let _=V(h(e.DRONE_COMMIT_AUTHOR)??h(e.DRONE_COMMIT_AUTHOR_NAME),h(e.DRONE_COMMIT_AUTHOR_EMAIL),"drone",h(e.DRONE_COMMIT_AUTHOR));if(_)return _;if(eo(e.CLAUDE_CODE_REMOTE)||eo(e.CURSOR_AGENT)){let E=h(e.CURSOR_USER_EMAIL);return{git_user_name:null,git_user_email:E&&!Q(null,E)?E:null,platform_login:null,identity_source:"cloud"}}return null}function Jt(e){return!!((e.git_user_name??e.git_user_email)&&!Q(e.git_user_name,e.git_user_email))}function h(e){if(e===void 0)return null;let t=e.trim();return t.length>0?t:null}function eo(e){if(e===void 0||e==="")return!1;let t=e.trim().toLowerCase();return t!=="0"&&t!=="false"&&t!=="no"}async function ac(e,t=C,n=process.env){let r=await rc(e,t);if(Jt(r))return{...r,identity_source:"git_config"};let o=oc(n);if(o&&Jt(o))return o;let s=ic(n);if(s&&(s.git_user_name||s.git_user_email||s.platform_login))return s;let a=await sc(e,t);return a&&Jt(a)?a:s||(r.git_user_name||r.git_user_email?{...r,identity_source:"git_config"}:o||a||{git_user_name:null,git_user_email:null,platform_login:null,identity_source:"git_config"})}async function Ye(e){let{gitRoot:t,installationStorePath:n,forceResend:r}=e,o=e.exec??C,s=e.env??process.env,a=await ac(t,o,s),i=tc(a.git_user_name,a.git_user_email,a.identity_source,a.platform_login),l=(n?Rt(n):void 0)?.operator_identity_hash;if(!(r||l!==void 0&&l!==i||!l))return{commit:()=>{}};let m=n;return{operator:a,commit:()=>{m&&Yn(m,i,He())}}}function Vt(e){return e?!Rt(e)?.operator_identity_hash:!0}function to(e){return!0}import{existsSync as bc,readFileSync as wc}from"node:fs";import{homedir as Io}from"node:os";import{join as L}from"node:path";import{basename as Tc,join as le,resolve as mo}from"node:path";import{existsSync as no,readdirSync as cc}from"node:fs";import{basename as lc,dirname as uc,relative as dc}from"node:path";var Oe=class{constructor(t,n=""){this.home=t;this.pathPrefix=n}components=[];truncated=!1;pluginExpandRemaining;homeRel(t){let n=dc(this.home,t).replace(/\\/g,"/"),r=!n||n.startsWith("..")?`external/${O(uc(t))}/${lc(t)}`:n;return this.pathPrefix?`${this.pathPrefix}${r}`:r}get atGlobalCap(){return this.truncated||this.components.length>=H}get pluginBudgetSpent(){return this.pluginExpandRemaining!==void 0&&this.pluginExpandRemaining<=0}readEntries(t){if(!no(t))return[];try{return cc(t,{withFileTypes:!0})}catch{return[]}}readJson(t,n){if(no(t))return ae(t,n)}push(t){return this.components.length>=H?(this.truncated=!0,!1):this.pluginExpandRemaining!==void 0&&this.pluginExpandRemaining<=0?!1:(this.pluginExpandRemaining!==void 0&&(this.pluginExpandRemaining-=1),this.components.push(t),!0)}withPluginExpandCap(t,n){let r=this.pluginExpandRemaining;this.pluginExpandRemaining=t;try{let o=n(),s=t-(this.pluginExpandRemaining??0);return{result:o,expanded:s}}finally{this.pluginExpandRemaining=r}}};import{existsSync as Wt,readFileSync as fc,statSync as pc}from"node:fs";import{basename as oo,join as Ae,relative as so}from"node:path";var zt=2e4,mc=4;function gc(e){return e.length<=zt?e:`${e.slice(0,zt-1)}\u2026`}function _c(e){try{let t=fc(e),n=t.toString("utf8");return{hash:O(t),length:t.length,text:gc(n)}}catch{return null}}var ro={HOOK:"EVENT",COMMAND:"EXPLICIT_INVOCATION",MEMORY:void 0,MCP_SERVER:void 0,PLUGIN:void 0,SKILL:"UNSPECIFIED",RULE:"UNSPECIFIED",SUBAGENT:"UNSPECIFIED"};function hc(e){return e in ro?ro[e]:"UNSPECIFIED"}function Xe(e,t){let n=_c(t.absolutePath);if(!n)return!1;let r=t.name??oo(t.absolutePath).replace(/\.(md|mdc|toml)$/i,""),o={kind:t.kind,name:r,path:e.homeRel(t.absolutePath),text:n.text,content_hash:n.hash,content_length:n.length,origin:t.origin,enabled:t.enabled},s=hc(t.kind);return s&&(o.trigger=s),e.push(o)}function Ec(e,t,n){let r=so(e,t).replace(/\\/g,"/");return!r||r.startsWith("..")?oo(t).replace(/\.(md|mdc|toml)$/i,""):n?r.replace(/\.(md|mdc|toml)$/i,""):r}function oe(e,t){let{dir:n,kind:r,origin:o,enabled:s,nested:a,extensions:i}=t;Yt(e,{walkRoot:n,currentDir:n,depth:0,kind:r,origin:o,enabled:s,nested:a,extensions:i})}function Yt(e,t){let{walkRoot:n,currentDir:r,depth:o,kind:s,origin:a,enabled:i,nested:c,extensions:l}=t;if(!(o>mc))for(let u of e.readEntries(r)){if(e.atGlobalCap){e.truncated=!0;return}if(e.pluginBudgetSpent)return;if(c){if(!u.isDirectory())continue;let m=Ae(r,u.name,c);if(Wt(m)){let _=so(n,Ae(r,u.name)).replace(/\\/g,"/");Xe(e,{absolutePath:m,kind:s,origin:a,enabled:i,name:_||u.name});continue}Yt(e,{walkRoot:n,currentDir:Ae(r,u.name),depth:o+1,kind:s,origin:a,enabled:i,nested:c,extensions:l});continue}if(u.isDirectory()){Yt(e,{walkRoot:n,currentDir:Ae(r,u.name),depth:o+1,kind:s,origin:a,enabled:i,nested:c,extensions:l});continue}if(!u.isFile()||!l)continue;let f=u.name.toLowerCase();if(!l.some(m=>f.endsWith(m)))continue;let g=Ae(r,u.name);Xe(e,{absolutePath:g,kind:s,origin:a,enabled:i,name:Ec(n,g,!0)})}}function io(e){for(let t of e)if(Wt(t))try{if(pc(t).size>0)return t}catch{continue}return e.find(t=>Wt(t))}function Sc(e){if(e.prompt||e.type==="prompt")return"prompt";let t=e.command??e.bash??e.powershell??"";return/\bnpx\b/i.test(t)?"npx":/\.(sh|bash|zsh|js|mjs|cjs|ts|py)(\s|$|"|')/i.test(t)||/^(\.\/|~\/|\/|[A-Za-z]:[\\/])/.test(t.trim())?"script":"inline"}function yc(e){return Array.isArray(e.hooks)&&e.hooks.length>0?e.hooks:[{type:e.type,command:e.command,bash:e.bash,powershell:e.powershell,prompt:e.prompt}]}function Ic(e,t,n,r){let o=e.homeRel(t);for(let[s,a]of Object.entries(n))if(!(!Array.isArray(a)||e.truncated))for(let i of a){if(!i||typeof i!="object"||e.truncated)continue;let c=i;for(let l of yc(c)){if(e.truncated)return;let u=l.command??l.bash??l.prompt??l.powershell??c.powershell??"",f=Sc({type:l.type??c.type,command:l.command??c.command,bash:l.bash??c.bash,powershell:l.powershell??c.powershell,prompt:l.prompt??c.prompt}),g=typeof c.matcher=="string"?c.matcher:"",m=O(u),_=g?`${s}:${g}:${f}:${m}`:`${s}:${f}:${m}`,E=`${s}|${g}|${f}|${u}`;e.push({kind:"HOOK",name:_,path:o,content_hash:O(E),origin:r,enabled:!0,trigger:"EVENT",attributes:{event:s,...g?{matcher:g}:{},action_kind:f,action_hash:m}})}}}function xe(e,t,n){let r=e.readJson(t,{});!r?.hooks||typeof r.hooks!="object"||Ic(e,t,r.hooks,n)}var ao={claude:{skillRoots:[".claude/skills"],dirs:[{dir:".claude/agents",kind:"SUBAGENT",extensions:[".md"]},{dir:".claude/commands",kind:"COMMAND",extensions:[".md"]}],memory:[".claude/CLAUDE.md"],hooks:[".claude/settings.json"],mcpJson:[".claude.json"],plugins:"claude"},cursor:{skillRoots:[".cursor/skills",".cursor/skills-cursor"],dirs:[{dir:".cursor/agents",kind:"SUBAGENT",extensions:[".md"]},{dir:".cursor/commands",kind:"COMMAND",extensions:[".md"]},{dir:".cursor/rules",kind:"RULE",extensions:[".mdc",".md"]}],memory:[".cursor/AGENTS.md"],hooks:[".cursor/hooks.json"],mcpJson:[".cursor/mcp.json"],plugins:"cursor"},codex:{skillRoots:[".agents/skills",".codex/skills"],dirs:[{dir:".codex/agents",kind:"SUBAGENT",extensions:[".toml",".md"]},{dir:".codex/prompts",kind:"COMMAND",extensions:[".md"]}],memory:[".codex/AGENTS.override.md",".codex/AGENTS.md"],hooks:[".codex/hooks.json"],mcpToml:[".codex/config.toml"]}};import{existsSync as Rc,readFileSync as kc}from"node:fs";function Cc(e){if(!e||typeof e!="object"||Array.isArray(e))return"unknown";let t=e;return typeof t.type=="string"&&t.type.length>0?t.type:typeof t.url=="string"?"http":typeof t.command=="string"?"stdio":"unknown"}function co(e,t,n){let o=e.readJson(t,{})?.mcpServers;if(!o||typeof o!="object")return;let s=e.homeRel(t);for(let[a,i]of Object.entries(o)){if(e.truncated)return;let c=Cc(i);e.push({kind:"MCP_SERVER",name:a,path:s,content_hash:O(`${a}|${c}`),origin:n,enabled:!0,attributes:{transport:c}})}}function lo(e,t,n){if(!Rc(t))return;let r;try{r=kc(t,"utf8")}catch{return}let o=e.homeRel(t),s=/^\[mcp_servers(?:\.(\w+)|\."([^"]+)"|\.'([^']+)')\]\s*$/gm,a;for(;(a=s.exec(r))!==null;){if(e.truncated)return;let i=a[1]??a[2]??a[3];if(!i)continue;let c=r.slice(a.index+a[0].length),l=c.search(/^\[/m),u=l===-1?c:c.slice(0,l),f="unknown";/^\s*url\s*=/m.test(u)?f="http":/^\s*command\s*=/m.test(u)&&(f="stdio"),e.push({kind:"MCP_SERVER",name:i,path:o,content_hash:O(`${i}|${f}`),origin:n,enabled:!0,attributes:{transport:f}})}}import{existsSync as Oc,readdirSync as Ac}from"node:fs";import{join as x}from"node:path";var uo=50;function Xt(e,t,n,r){if(!Oc(t))return{componentCount:0,expandTruncated:!1};let o=e.components.length,{expanded:s}=e.withPluginExpandCap(uo,()=>{oe(e,{dir:x(t,"skills"),kind:"SKILL",origin:n,enabled:r,nested:"SKILL.md"}),oe(e,{dir:x(t,"commands"),kind:"COMMAND",origin:n,enabled:r,extensions:[".md"]}),oe(e,{dir:x(t,"agents"),kind:"SUBAGENT",origin:n,enabled:r,extensions:[".md"]})});xe(e,x(t,"hooks","hooks.json"),n),xe(e,x(t,"hooks.json"),n);let a=e.components.length-o,i=s>=uo;return{componentCount:a,expandTruncated:i}}function qt(e,t){e.push({kind:"PLUGIN",name:t.pluginKey,path:t.rowPath,content_hash:t.contentHash,origin:"user",enabled:t.enabled,attributes:{...t.marketplace?{marketplace:t.marketplace}:{},...t.version?{version:t.version}:{},scope:t.scope,component_count:t.componentCount,...t.expandTruncated?{expand_truncated:!0}:{}}})}function fo(e){let t=x(e.home,".claude/plugins/installed_plugins.json"),n=e.readJson(t,{});if(!n)return;let r=n.plugins??{},s=e.readJson(x(e.home,".claude/settings.json"),{})?.enabledPlugins??{},a=e.homeRel(t);for(let[i,c]of Object.entries(r)){if(e.truncated)return;let l=Array.isArray(c)?c:[c],u=l[0]??{},f=s[i]===!0,g=i.includes("@")?i.split("@").slice(1).join("@"):"",m=typeof u.version=="string"?u.version:"",_=typeof u.scope=="string"?u.scope:"user",E=`plugin:${i}`,T=0,A=!1;for(let P of l)if(typeof P.installPath=="string"&&P.installPath.length>0){let Z=Xt(e,P.installPath,E,f);T+=Z.componentCount,A=A||Z.expandTruncated}qt(e,{pluginKey:i,rowPath:a,enabled:f,scope:_,version:m||void 0,marketplace:g||void 0,componentCount:T,expandTruncated:A,contentHash:O(`${i}|${m}|${_}|${f}|${T}`)})}}function xc(e){let t=e,n="";try{let r=Ac(e,{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>o.name);if(r.length===1&&r[0])t=x(e,r[0]),n=r[0];else if(r.length>1){let o=[...r].sort(),s=o[o.length-1];s&&(t=x(e,s),n=s)}}catch{}return{installPath:t,version:n}}function po(e){let t=[{base:x(e.home,".cursor/plugins/local"),scope:"local"},{base:x(e.home,".cursor/plugins/cache"),scope:"cache"}];for(let{base:n,scope:r}of t)if(!e.truncated)for(let o of e.readEntries(n)){if(!o.isDirectory()||e.truncated)continue;if(r==="local"){let a=o.name,i=x(n,o.name),c=`plugin:${a}`,{componentCount:l,expandTruncated:u}=Xt(e,i,c,!0);qt(e,{pluginKey:a,rowPath:e.homeRel(i),enabled:!0,scope:"local",componentCount:l,expandTruncated:u,contentHash:O(`${a}|local|${l}`)});continue}let s=o.name;for(let a of e.readEntries(x(n,s))){if(!a.isDirectory()||e.truncated)continue;let i=x(n,s,a.name),{installPath:c,version:l}=xc(i),u=`${a.name}@${s}`,f=`plugin:${u}`,{componentCount:g,expandTruncated:m}=Xt(e,c,f,!0);qt(e,{pluginKey:u,rowPath:e.homeRel(c),enabled:!0,scope:"cache",version:l||void 0,marketplace:s,componentCount:g,expandTruncated:m,contentHash:O(`${u}|${l}|${g}`)})}}}function go(e,t,n,r){let o=ao[t];if(!o)return;let s=e.home;for(let i of o.skillRoots)oe(e,{dir:le(s,i),kind:"SKILL",origin:n,enabled:!0,nested:"SKILL.md"});for(let i of o.dirs)oe(e,{dir:le(s,i.dir),kind:i.kind,origin:n,enabled:!0,extensions:i.extensions});let a=io(o.memory.map(i=>le(s,i)));a&&Xe(e,{absolutePath:a,kind:"MEMORY",origin:n,enabled:!0,name:Tc(a)});for(let i of o.hooks)xe(e,le(s,i),n);for(let i of o.mcpJson??[])co(e,le(s,i),n);for(let i of o.mcpToml??[])lo(e,le(s,i),n);r&&(o.plugins==="claude"?fo(e):o.plugins==="cursor"&&po(e))}function Zt(e,t,n){let r=new Oe(t);if(go(r,e,"user",!0),n===void 0||mo(n)===mo(t))return{components:r.components,truncated:r.truncated};let s=new Oe(n,"cwd/");go(s,e,"cwd",!1);let a=[...r.components,...s.components],i=r.truncated||s.truncated||a.length>H;return{components:a.slice(0,H),truncated:i}}function Qt(e,t,n={}){let r=n.truncated===!0,o=Kt(e),s=new Set(e.map(u=>J(u.path,u.name)));if(n.forceFull===!0||t===void 0)return{hash:o,count:e.length,truncated:r,full:!0,upserts:e,removed:[],unchanged:!1};let i=[],c=t;for(let u of e){let f=J(u.path,u.name);c[f]!==u.content_hash&&i.push(u)}let l=[];if(!r){for(let u of Object.keys(c))if(!s.has(u)){let f=Qr(u);f&&l.push(f)}}return{hash:o,count:e.length,truncated:r,full:!1,upserts:i,removed:l,unchanged:i.length===0&&l.length===0}}var ho=3e5,vc=new Set(["HOOK","MCP_SERVER","PLUGIN"]);function en(e,t,n){let r=new Set(t.map(s=>J(s.path,s.name))),o=[];for(let s of e)s.text!==void 0&&(n.has(s.content_hash)||r.has(J(s.path,s.name))||o.push(s));return o}function tn(e,t,n){let r=new Set(e);for(let s of t)r.add(s);let o=new Set(n.map(s=>s.content_hash));return[...r].filter(s=>o.has(s))}function _o(e){return Buffer.byteLength(JSON.stringify(e),"utf8")}function Eo(e){if(e.text===void 0)return e;let{text:t,...n}=e;return n}function nn(e,t=ho){let n=[],r=[];for(let u of e)vc.has(u.kind)?n.push(u):r.push(u);r.sort((u,f)=>(u.text?.length??0)-(f.text?.length??0));let o=[...n,...r],s=[],a=2,i=0,c=0,l=[];for(let u of o){let f=s.length>0?1:0,g=_o(u)+f;if(a+g<=t){s.push(u),a+=g,u.text!==void 0&&l.push(u.content_hash);continue}if(u.text!==void 0){let m=Eo(u),_=_o(m)+f;if(a+_<=t){s.push(m),a+=_,i+=1;continue}}c+=1}return{components:s,textDeferredCount:i,droppedCount:c,textHashesSent:l}}function rn(e,t){return t.size===0?e:e.map(n=>n.text===void 0||!t.has(n.content_hash)?n:Eo(n))}var Pc={claude:{skills:".claude/skills",subagents:".claude/agents",commands:".claude/commands",memory:".claude/CLAUDE.md",settings:".claude/settings.json"},cursor:{skills:[".cursor/skills",".cursor/skills-cursor"],subagents:".cursor/agents",commands:".cursor/commands",rules:".cursor/rules",mcp:".cursor/mcp.json"},codex:{skills:[".agents/skills",".codex/skills"],subagents:".codex/agents",commands:".codex/prompts",memory:".codex/AGENTS.md",settings:".codex/config.toml"}},Nc=200,So=200,Uc=["allow","deny","ask"],Lc=/(?<=^|[\s(,=:])(?:~|[A-Za-z]:)?[\\/][^\s,)]+/g,on="<path>",Mc=new RegExp(`${on}(?:\\s+[A-Za-z.][^\\s,)]*[\\\\/][^\\s,)]*)+`,"g");function Hc(e){let t=e.replace(Lc,on).replace(Mc,on);return t.length>So?`${t.slice(0,So)}...`:t}function yo(e){let t=ae(e,{}),n=[];for(let r of Uc)for(let o of t.permissions?.[r]??[])typeof o=="string"&&o.length>0&&n.push({key:Hc(o),mode:r});return{model:t.model??"",permissionKeys:n}}var Dc=10,Fc=840*60*1e3,$c="self-config-cache.json";function sn(){return k("EV_AI_HOOK_USER_SPEC")?.toLowerCase()==="off"}function Bc(e,t=Date.now()){return e===void 0||!Number.isFinite(e)?!0:t-e>=Fc}var jc={claude:["claude"],cursor:["agent","cursor-agent"],codex:["codex"]};async function Gc(e,t=C){let n=jc[e];if(!n||n.length===0)return null;let r=async o=>{let s=n[o];if(s===void 0)return null;let i=((await t(s,["--version"],2e3)).split(`
|
|
22
|
+
`)[0]??"").trim();return i||r(o+1)};return r(0)}function Kc(e=Io()){return L(e,".ev-ai","agent-hook",$c)}function Jc(e){let n=[...e].sort((r,o)=>r.name.localeCompare(o.name)).map(r=>`${r.name}:${r.size}`).join(`
|
|
23
|
+
`);return O(n)}function qe(e,t,n=!1){let r=Jc(e),o=e.length;return t===r?n?{hash:r,count:o,truncated:n}:{hash:r,count:o}:n?{hash:r,count:o,entries:e,truncated:n}:{hash:r,count:o,entries:e}}function Vc(e){return bc(e)?w(wc(e,"utf8"),{}):{}}function Wc(e,t){try{Y(e,`${JSON.stringify(t)}
|
|
24
|
+
`)}catch(n){let r=n instanceof Error?n.message:String(n);d(`WARN: self-config cache write failed open: ${r}`)}}function zc(e,t,n,r){let o={...e,send_count:n};for(let s of Object.keys(t)){let a=t[s];a.entries!==void 0&&(o[s]=a.hash)}return r&&(o.user_spec_collected_at_ms=r.collectedAtMs,r.included&&(o.user_spec=r.hash,o.user_spec_components=r.componentHashes),o.user_spec_text_hashes=r.textHashes),o}async function Ro(e,t=process.cwd(),n=Io(),r={}){let o=e==="claude",s=r.gitRoot??t,a=await Gc(e),i="",c=[];if(o){let N=yo(L(n,".claude/settings.json")),D=yo(L(t,".claude/settings.local.json"));i=D.model||N.model,c=[...N.permissionKeys,...D.permissionKeys].slice(0,Nc)}let l=Pc[e]??{},u={present:!1,size:0},f=N=>{let D=Array.isArray(N)?N:N?[N]:[],R=[],W=!1;for(let ot of D){let b=_e(L(n,ot));if(R=R.concat(b.entries),W=W||b.truncated,R.length>=H){R=R.slice(0,H),W=!0;break}}return{entries:R,truncated:W}},g=Kc(n),m=Vc(g),_=m[e]??{},E=(_.send_count??0)+1,T=E>0&&E%Dc===0,A=N=>T?void 0:_[N],P=f(l.skills),Z=l.subagents?_e(L(n,l.subagents)):{entries:[],truncated:!1},rt=l.commands?_e(L(n,l.commands)):{entries:[],truncated:!1},cn=l.rules?_e(L(n,l.rules)):{entries:[],truncated:!1},fe={skills:qe(P.entries,A("skills"),P.truncated),subagents:qe(Z.entries,A("subagents"),Z.truncated),commands:qe(rt.entries,A("commands"),rt.truncated),rules:qe(cn.entries,A("rules"),cn.truncated)},v={runner_platform:e,config_scope:"user",cli_version:a,claude_version:o?a:null,model:o&&i||null,permission_keys:c,user_scope:{skills:fe.skills,subagents:fe.subagents,commands:fe.commands,rules:fe.rules,memory:l.memory?he(L(n,l.memory)):u,settings:l.settings?he(L(n,l.settings)):u,mcp:l.mcp?he(L(n,l.mcp)):u},local_settings:o?he(L(t,".claude/settings.local.json")):u},ln=null,un=()=>{},dn=r.nowMs??Date.now();if(!sn()&&Bc(_.user_spec_collected_at_ms,dn)){let N=_.user_spec_collected_at_ms!==void 0,D=Zt(e,n),R=Qt(D.components,_.user_spec_components,{forceFull:!_.user_spec_components,truncated:D.truncated}),W=new Set(_.user_spec_text_hashes??[]),ot=en(D.components,R.upserts,W),b=nn(rn([...R.upserts,...ot],W));v.user_spec_hash=R.hash,v.user_spec_count=R.count,v.user_spec_truncated=R.truncated||b.droppedCount>0,(b.components.length>0||R.removed.length>0||R.full)&&(R.full&&(v.user_spec_full=!0),b.components.length>0&&(v.user_spec=b.components),R.removed.length>0&&!v.user_spec_truncated&&(v.user_spec_removed=R.removed),b.textDeferredCount>0&&(v.user_spec_text_deferred=b.textDeferredCount));let st=R.full?{}:{..._.user_spec_components??{}};if(!v.user_spec_truncated)for(let ie of R.removed)delete st[J(ie.path,ie.name)];for(let ie of b.components)st[J(ie.path,ie.name)]=ie.content_hash;ln={hash:R.hash,componentHashes:st,textHashes:tn(W,b.textHashesSent,D.components),included:b.components.length>0||R.removed.length>0&&!v.user_spec_truncated||R.full,collectedAtMs:dn};let it=await Ye({gitRoot:s,installationStorePath:r.installationStorePath,forceResend:N});it.operator&&(v.operator=it.operator),un=it.commit}let Do=zc(_,fe,E,ln);return{config:v,commit:()=>{m[e]=Do,Wc(g,m),un()}}}function ue(e,t,n){let r={installation_id:n.installationId};return n.platformAgentId&&(r.platform_agent_id=n.platformAgentId),n.sessionId&&(r.session_id=n.sessionId),n.turnId&&(r.turn_id=n.turnId),{schema_version:2,event:e,timestamp:He(),session_id:n.sessionId||null,turn_id:n.turnId||null,installation_id:n.installationId,platform:n.runnerPlatform,platform_agent_id:n.platformAgentId||null,runner_event:n.runnerEvent||null,agent_hook_version:F,host_arch:process.arch,node_version:process.version,correlation:r,payload:t}}import{existsSync as ko}from"node:fs";import{spawn as Co}from"node:child_process";import{basename as Yc}from"node:path";import{fileURLToPath as Xc}from"node:url";var Te="__post",Ze="__work";function qc(e,t){let n=e.payload,r=n&&typeof n=="object"&&!Array.isArray(n)?Object.keys(n):[],o=e.correlation&&typeof e.correlation=="object"?Object.keys(e.correlation):[];return JSON.stringify({event:e.event,schema_version:e.schema_version,agent_hook_version:e.agent_hook_version,host_arch:e.host_arch,node_version:e.node_version,build_ms:e.build_ms,body_bytes:t,correlation_keys:o,payload_keys:r})}function Oo(e){switch(e){case"session_start":return _n;case"session_end":return hn;case"tool_invoked":case"skill_invoked":return lt;default:return lt}}function Zc(e,t,n){return`${JSON.stringify({url:e,timeoutMs:t})}
|
|
25
|
+
${n}`}function Ao(e,t=[],n=process.execPath,r=import.meta.url,o=ko){if(Yc(n)===z)return{command:n,args:[e,...t]};let s=Xc(r);return o(s)?{command:n,args:[s,e,...t]}:{command:n,args:[e,...t]}}function Qc(e=process.execPath,t=import.meta.url,n=ko){return Ao(Te,[],e,t,n)}function el(e){let t=e.indexOf(`
|
|
26
|
+
`);if(t<0)return null;let n;try{n=JSON.parse(e.slice(0,t))}catch{return null}return{meta:n,body:e.slice(t+1)}}async function Qe(e,t=fetch){let n=await e(),r=el(n);if(!r)return;let{meta:o,body:s}=r,a={"Content-Type":"application/json"};try{await t(o.url,{method:"POST",headers:a,body:s,signal:AbortSignal.timeout(Number(o.timeoutMs))})}catch{}}async function tl(e,t,n){let r=Oo(e);d(`POST event=${e} url=${dt(n)} size=${t.length} platform=${process.platform}`);let o={"Content-Type":"application/json"},s=Date.now();try{let a=await fetch(n,{method:"POST",headers:o,body:t,signal:AbortSignal.timeout(r)}),i=Date.now()-s;if(a.ok)return d(`POST outcome=ok elapsed_ms=${i} http=${a.status}`),!0;let c=(await a.text()).slice(0,200).replace(/[\n\r]/g,"");return d(`POST outcome=fail elapsed_ms=${i} http=${a.status} body=${c}`),!1}catch(a){let i=Date.now()-s,c=a instanceof Error?a.message:String(a);return d(`POST outcome=fail elapsed_ms=${i} http=000 body=${c}`),!1}}async function xo(e,t,n,r,o){try{let s=r(e,t,{detached:!0,stdio:["pipe","ignore","ignore"],windowsHide:!0});s.on("error",()=>{}),s.stdin.on("error",()=>{});let a=!1;return await new Promise(i=>{let c=setTimeout(()=>{if(!a){d(`WARN: ${o} stdin handoff timed out \u2014 continuing fail-open`);try{s.stdin.destroy()}catch{}}i()},En),l=()=>{a=!0,clearTimeout(c),i()};s.stdin.end(n,()=>l()),s.stdin.once("error",()=>l())}),s.unref(),s}catch(s){let a=s instanceof Error?s.message:String(s);return d(`WARN: ${o} spawn failed open: ${a}`),null}}async function nl(e,t,n,r=Co,o=Qc){let s=Oo(e),a=Zc(n,s,t),{command:i,args:c}=o();return xo(i,c,a,r,"detached post")}async function To(e,t,n=Co,r=Ao){let{command:o,args:s}=r(Ze,t);return xo(o,s,e,n,"detached work")}async function de(e,t,n,r,o,s){if(!o)return d("WARN: collector URL missing \u2014 pass --url on the hook command or set collector_url in manifest"),!1;if(!Me(o))return d(`WARN: collector URL blocked (https required): ${dt(o)}`),!1;let a=r(e,t,n);s!==void 0&&(a.build_ms=Math.max(0,Date.now()-s));let i=`${JSON.stringify(a)}
|
|
27
|
+
`,c=k("EV_AI_HOOK_DEBUG");c==="full"?d(`DEBUG envelope=${JSON.stringify(a)}`):c==="1"&&d(`DEBUG summary=${qc(a,Buffer.byteLength(i,"utf8"))}`);let l=process.argv.includes(Ze),u=k("EV_AI_HOOK_SYNC")==="1";return We(n.runnerEvent,n.runnerPlatform)||l||u?tl(e,i,o):(await nl(e,i,o),!1)}import{relative as rl,resolve as et,sep as an}from"node:path";var ol=["session_id","conversation_id","turn_id","generation_id","prompt.id","prompt_id","hook_event_name","event","source","status","stop_reason","reason","tool_name","tool","tool_use_id","skill_name","command_name","expansion_type","command_source","permission_mode","model","model_id","agent_id","agent_type","subagent_id","subagent_type","subagent_model","is_parallel_worker","effort","effort.level","duration_ms","duration","sandbox","failure_type","is_interrupt"];function sl(e){return e.capture_hook_input==="full"?!0:e.capture_hook_input==="allowlist"?!1:k("EV_AI_HOOK_CAPTURE_FULL_INPUT")==="1"}function il(e){let t={};for(let n of ol){let r=te(e,n);r!==void 0&&(t[n]=r)}return t}function al(e,t){if(typeof e!="string"||e.length===0||!t)return null;let n=et(e),r=et(t),o=rl(r,n);return!o||o==="."?".":o.startsWith(`..${an}`)||o===".."||et(r,o)!==n?null:o.split(an).join("/")}function cl(e){return typeof e!="string"||e.length===0?null:et(e).split(an).join("/")}function vo(e,t,n){let r=cl(t.cwd);r!==null&&(e.cwd=r);let o=n.inGitRepo===!0&&n.gitRoot!==void 0?al(t.cwd,n.gitRoot):null;o!==null&&(e.cwd_relative=o)}function bo(e,t){let n=JSON.stringify(e),r=Buffer.byteLength(n,"utf8");if(r<=t)return e;let o=Object.entries(e).filter(([a,i])=>!a.startsWith("_")&&(typeof i=="string"||typeof i=="number"||typeof i=="boolean")).sort((a,i)=>Buffer.byteLength(JSON.stringify(a[1]),"utf8")-Buffer.byteLength(JSON.stringify(i[1]),"utf8")),s={_truncated:!0,_original_bytes:r};for(let[a,i]of o){let c={...s,[a]:i};if(Buffer.byteLength(JSON.stringify(c),"utf8")>t)break;s[a]=i}return s}function ve(e,t,n={}){if(sl(t)){let o={...e};return delete o.cwd,delete o.transcript_path,vo(o,e,n),bo(o,yn)}let r=il(e);return vo(r,e,n),bo(r,Sn)}import{createReadStream as ll}from"node:fs";import{stat as ul}from"node:fs/promises";import{basename as dl,resolve as fl}from"node:path";import{createInterface as pl}from"node:readline";var ml=1024*1024;function gl(e){let t=e.replace(/\\/g,"/");return t.includes("/.claude/projects/")&&dl(t).endsWith(".jsonl")}async function wo(e){if(!e||!gl(e))return null;try{let t=fl(e),n=await ul(t);if(!n.isFile())return null;let r=Math.max(0,n.size-ml),o=[],s=pl({input:ll(t,{encoding:"utf8",start:r}),crlfDelay:1/0});for await(let a of s)a.length!==0&&o.push(a);r>0&&o.length>0&&o.shift();for(let a=o.length-1;a>=0;a--){let i=o[a];if(i)try{let c=JSON.parse(i);if(c.type!=="assistant")continue;let l=c.message;if(!l||typeof l!="object")continue;let u=l.model;if(typeof u=="string"&&u.length>0)return u}catch{continue}}return null}catch{return null}}function we(e){return{sessionId:e.sessionId,turnId:e.turnId,installationId:e.manifest.installationId,runnerPlatform:e.runnerPlatform,platformAgentId:e.platformAgentId,runnerEvent:e.runnerEvent}}function tt(e){return{gitRoot:e.manifest.gitRoot,inGitRepo:e.manifest.inGitRepo}}var _l=new Set([...Object.values(Dt),".github"]);function hl(e,t,n){if(e===null||t===null||n===null||!(/^mcp__.+?__.+$/i.test(e)||/^MCP:[^:]+:.+$/i.test(e)||e.toLowerCase()===`mcp:${t.toLowerCase()}`))return;let o=n.indexOf(":");if(o<=0||o===n.length-1)return;let s=n.slice(o+1),a=s.replaceAll("\\","/").split("/").at(-1);if(!(a===void 0||!_l.has(a)))try{return(0,q.buildComponentReference)({installationRootExternalKey:n,installableKind:q.ComponentKind.INTERFACE,sourcePath:s,nativeKey:t})}catch{return}}function El(...e){for(let t of e)if(t)return t;return null}function M(e,t,n){if(e.status==="fulfilled")return e.value;let r=e.reason instanceof Error?e.reason.message:String(e.reason);return d(`WARN: ${n} failed open: ${r}`),t}function Sl(e){let t={present:!1,size:0},n={hash:"",count:0};return{config:{runner_platform:e,config_scope:"user",cli_version:null,claude_version:null,model:null,permission_keys:[],user_scope:{skills:n,subagents:n,commands:n,rules:n,memory:t,settings:t,mcp:t},local_settings:t},commit:()=>{}}}function yl(e,t){return{runner_platform:e,config_scope:"user",...t?{operator:t}:{}}}var se=new Set,be=null;async function Po(e){if(sn())return;let t=e.manifest.installationId,n=e.manifest.installationStorePath;if(se.has(t))return;if(!Vt(n)){se.add(t);return}let r=Se({sessionId:e.sessionId,hostname:ye()});if(to(r)){if(be){await be;return}be=(async()=>{if(se.has(t)||!Vt(n)){se.add(t);return}if(!Xn(n)){se.add(t);return}let o=!1;try{let s=Date.now(),{gitRoot:a}=e.manifest,i=String(e.runnerPlatform),[c,l,u,f,g]=await Promise.allSettled([Ce(a),ht(),Ft(r),Et(),Ye({gitRoot:a,installationStorePath:n,forceResend:!1})]),m=M(c,null,"gitSnapshot"),_=M(l,"","detectVirt"),E=M(u,null,"probeCloud"),T=M(f,{},"hostEnv"),A=M(g,{commit:()=>{}},"resolveOperatorForSend");await Pe(e,a,m);let P={identity:{host:ye(),context:r,virt:_||null,cloud:E,git:m},host_env:T,env_vars:Gt(),self_config:yl(i,A.operator),run_meta:{trigger:"cloud_identity_bootstrap"}};o=!!await de("session_start",P,we(e),ue,e.manifest.collectorUrl,s),o&&(A.commit(),se.add(t))}finally{qn(n)}})().finally(()=>{be=null}),await be}}async function Pe(e,t,n){try{let r=n===void 0?await Ce(t):n;e.platformAgentId=await zr(e.manifest.manifest,e.platformAgentId,String(e.runnerPlatform),t,r,e.manifest.installationStorePath,e.manifest.repoKey)}catch(r){let o=r instanceof Error?r.message:String(r);d(`WARN: derivePlatformAgentId failed open: ${o}`)}}async function Il(e){let t=Date.now(),{gitRoot:n}=e.manifest,r=Se({sessionId:e.sessionId,hostname:ye()}),o=String(e.runnerPlatform),[s,a,i,c,l,u]=await Promise.allSettled([Ce(n),ht(),Ft(r),Et(),jt(e.manifest.manifest,n,o),Ro(o,n,void 0,{installationStorePath:e.manifest.installationStorePath,gitRoot:n})]),f=M(s,null,"gitSnapshot"),g=M(a,"","detectVirt"),m=M(i,null,"probeCloud"),_=M(c,{},"hostEnv"),E=M(l,[],"mcpDeclared"),T=M(u,Sl(o),"selfConfig"),A=T.config;await Pe(e,n,f);let P=p(e.hookInput,"model");P&&(A.model=P);let Z={identity:{host:ye(),context:r,virt:g||null,cloud:m,git:f},host_env:_,env_vars:Gt(),mcp:{declared:E},self_config:A,run_meta:{trigger:e.hookSource||"startup"},hook_input:ve(e.hookInput,e.manifest.manifest,tt(e))};await de("session_start",Z,we(e),ue,e.manifest.collectorUrl,t)&&(T.commit(),se.add(e.manifest.installationId))}async function Rl(e){let t=Date.now(),{gitRoot:n}=e.manifest;await Pe(e,n);let r=El(p(e.hookInput,"status"),p(e.hookInput,"stop_reason"),p(e.hookInput,"reason"),Mt(p(e.hookInput,"error"))),o=e.runnerPlatform==="claude"?await wo(p(e.hookInput,"transcript_path")):null,s=ve(e.hookInput,e.manifest.manifest,tt(e));o&&(s.model=o),await de("session_end",{status:r,...o?{model:o}:{},hook_input:s},we(e),ue,e.manifest.collectorUrl,t)}async function kl(e){let t=Date.now(),n=wr(e.hookInput);if(n.length===0)return;await Po(e);let{gitRoot:r}=e.manifest;await Pe(e,r);let o=ve(e.hookInput,e.manifest.manifest,tt(e)),s=we(e),a=Ke(e.hookInput.tool_input),i=r.replaceAll("\\","/").replace(/\/$/,""),c=a?.replaceAll("\\","/"),l=c===void 0?null:c.startsWith(`${i}/`)?c.slice(i.length+1):c.startsWith("/")?null:c;await Promise.all(n.map(u=>{let f;if(l!==null&&Pt(l)?.toLowerCase()===u.toLowerCase()&&e.platformAgentId){let g=(0,q.nativeKeyForSkillPath)(l);if(g!==null)try{f=(0,q.buildComponentReference)({installationRootExternalKey:e.platformAgentId,installableKind:q.ComponentKind.SKILL,sourcePath:l,nativeKey:g})}catch{f=void 0}}return de("tool_invoked",{tool_name:"Skill",skill_name:u,...f===void 0?{}:{component_reference:f},success:null,duration_ms:null,hook_input:o},s,ue,e.manifest.collectorUrl,t)}))}async function Cl(e){let t=Date.now();await Po(e);let{gitRoot:n}=e.manifest;await Pe(e,n);let{toolName:r,skillName:o}=Mr(e.hookInput,e.runnerEvent),s=Dr(e.hookInput),a=Nr(e.runnerEvent),i=a===!1?Fr(e.hookInput,e.runnerEvent):null,c=await jt(e.manifest.manifest,e.manifest.gitRoot,String(e.runnerPlatform)).catch(()=>[]),{mcpServer:l,mcpTool:u}=$r(r,c.map(m=>m.name)),f=hl(r,l,e.platformAgentId),g=Hr(e.hookInput);await de("tool_invoked",{tool_name:r,skill_name:o,success:a,duration_ms:s,...i?{failure_reason:i}:{},...l?{mcp_server:l}:{},...u?{mcp_tool:u}:{},...f?{component_reference:f}:{},...g?{subagent_type:g}:{},hook_input:ve(e.hookInput,e.manifest.manifest,tt(e))},we(e),ue,e.manifest.collectorUrl,t)}async function No(e){switch(e.internalEvent){case"session_start":await Il(e);return;case"session_end":await Rl(e);return;case"skill_invoked":await kl(e);return;case"tool_invoked":await Cl(e);return;default:return}}function Uo(e){return e!=="session_start"&&e!=="session_end"&&e!=="tool_invoked"&&e!=="skill_invoked"&&e!==""}async function Lo(e,t,n,r){let o=t??await mt(ut),s=w(o,{}),a=p(s,"session_id")||p(s,"conversation_id"),i=await nr(process.cwd(),{sessionId:a});if(!i)return;r&&(i.collectorUrl=r);let c=Ur(s,i.manifest.platform,n),l=Lr(e,c.runnerEvent);if(!l){d(`WARN: unknown hook event '${c.runnerEvent}'; skipping telemetry`);return}let u={hookInput:s,sessionId:c.sessionId,turnId:c.turnId,runnerEvent:c.runnerEvent,runnerPlatform:c.runnerPlatform,hookSource:c.hookSource,internalEvent:l,manifest:i,platformAgentId:i.platformAgentId};if(Uo(l)){d(`WARN: unsupported internal event '${l}'`);return}await No(u)}function Ol(e,t){if(k("EV_AI_HOOK_SYNC")==="1")return!0;let n=Ve(e),r=w(t,{}),o=n.event??(p(r,"hook_event_name")||p(r,"event")),s=Re(r,o,void 0,n.runner);return We(o,s)}async function Mo(e=process.argv.slice(2)){if(e[0]===Te){try{await Qe(ge)}catch{}return 0}if(e[0]===Ze){try{let t=Ve(e.slice(1)),n=await ge(),r=w(n,{}),o=t.event??(p(r,"hook_event_name")||p(r,"event"));if(Lt(t.runner,r,o))return 0;await Lo(t.event,n,t.runner,Ut(t))}catch(t){let n=t instanceof Error?t.message:String(t);d(`WARN: detached work failed open: ${n}`)}return 0}try{let t=await mt(ut),n=Ve(e),r=Ut(n),o=w(t,{}),s=n.event??(p(o,"hook_event_name")||p(o,"event"));if(Lt(n.runner,o,s)||!Wr(o,s,n.runner))return 0;Ol(e,t)?await Lo(n.event,t,n.runner,r):await To(t,e)}catch(t){let n=t instanceof Error?t.message:String(t);d(`WARN: hook failed open: ${n}`)}finally{wn()}return 0}function nt(){d("Usage: ev-ai-agent-hook <configure|install|migrate-to-plugin|update|uninstall|--version>"),d(" configure [--url <\u2026/{orgToken}/hook>]"),d(" (manifest only \u2014 pair with marketplace plugins)"),d(" install --url <\u2026/{orgToken}/hook>"),d(" [--delivery npx|binary|local] [--force]"),d(" [--no-claude] [--no-cursor] [--no-codex]"),d(" (fallback: merge hooks into .claude / .cursor / .codex configs)"),d(" (writes collector_url to shared manifest; hook commands use --runner only)"),d(" migrate-to-plugin"),d(" (strip ev-ai file hooks; keep collector manifest)"),d(" update (refresh binary pins from a local build; leaves hook configs alone)"),d(" uninstall"),d("Hook mode: --runner <platform> [--url <\u2026/hook>|--token <orgToken>] [event]"),d(" (--url/--token optional overrides; else collector_url from manifest)")}function Ho(e){return e.includes("--help")||e.includes("-h")}async function bl(e=process.argv.slice(2)){let[t,...n]=e;if(t===Te){try{await Qe(ge)}catch{}return 0}return t==="--version"||t==="-V"?(process.stdout.write(`${F}
|
|
28
|
+
`),0):t==="configure"?Ho(n)?(nt(),0):(await Cr(ur(n)),0):t==="install"?Ho(n)?(nt(),0):(await Rr(dr(n)),0):t==="migrate-to-plugin"?(await Ar(),0):t==="update"?(await kr(),0):t==="uninstall"?(await xr(),0):t==="help"||t==="--help"||t==="-h"?(nt(),0):t===void 0?(nt(),1):Mo(e)}function wl(e,t,n=Al){if(!t)return!1;try{return e===vl(xl(t)).href?!0:n(Tl(e))===n(t)}catch{return!1}}wl(import.meta.url,process.argv[1])&&process.env.VITEST===void 0&&bl().then(e=>{process.exit(e)}).catch(e=>{let t=e instanceof Error?e.message:String(e);d(t),process.exit(1)});export{wl as isCliEntrypoint,bl as main};
|
package/dist/hook.mjs
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
`)}catch(s){let i=s instanceof Error?s.message:String(s);m(`WARN: platform_agent_id cache write failed open: ${i}`)}}function tn(e){return e instanceof Error&&"code"in e&&e.code==="EEXIST"}function wr(e,t){Gt(Le(e),{recursive:!0}),Vt(e,`${JSON.stringify(t,null,2)}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
`)
|
|
9
|
-
`)){let o=r.trim();if(!o)continue;let s=o.indexOf(" ");if(s<=0)continue;let i=o.slice(0,s).toLowerCase(),a=o.slice(s+1).trim();a&&(i==="user.name"?t=a:i==="user.email"&&(n=a))}return{git_user_name:t,git_user_email:n,platform_login:null}}async function uo(e,t=R){let n=await t("git",["config","--get-regexp","^user\\.(name|email)$"],2e3,{cwd:e});return lo(n)}function po(e=process.env){let t=_(e.GIT_AUTHOR_NAME),n=_(e.GIT_AUTHOR_EMAIL);if(t||n)return{git_user_name:t,git_user_email:n,platform_login:null,identity_source:"git_env"};let r=_(e.GIT_COMMITTER_NAME),o=_(e.GIT_COMMITTER_EMAIL);if(r||o)return{git_user_name:r,git_user_email:o,platform_login:null,identity_source:"git_env"};let s=_(e.EMAIL);return s?{git_user_name:null,git_user_email:s,platform_login:null,identity_source:"git_env"}:null}async function fo(e,t=R){let n=await t("git",["log","-1","--format=%an%x00%ae"],2e3,{cwd:e});if(!n)return null;let r=n.indexOf("\0"),o=(r>=0?n.slice(0,r):n).trim(),s=(r>=0?n.slice(r+1):"").trim();return!o&&!s?null:{git_user_name:o||null,git_user_email:s||null,platform_login:null,identity_source:"git_log"}}function D(e,t,n,r=null){return!e&&!t&&!r?null:{git_user_name:e,git_user_email:t,platform_login:r,identity_source:n}}function mo(e=process.env){let t=D(_(e.EV_AI_HOOK_OPERATOR_NAME),_(e.EV_AI_HOOK_OPERATOR_EMAIL),"configured");if(t)return t;let n=_(e.GITHUB_ACTOR)??_(e.GITHUB_TRIGGERING_ACTOR)??_(e.GITHUB_USER),r=D(n,null,"github",n);if(r)return r;let o=_(e.GITLAB_USER_LOGIN),s=D(_(e.GITLAB_USER_NAME)??o,_(e.GITLAB_USER_EMAIL),"gitlab",o);if(s)return s;let i=D(_(e.BUILD_REQUESTEDFOR),_(e.BUILD_REQUESTEDFOREMAIL),"azure_devops");if(i)return i;let a=D(_(e.BUILDKITE_BUILD_CREATOR),_(e.BUILDKITE_BUILD_CREATOR_EMAIL),"buildkite");if(a)return a;let c=D(_(e.BUILD_USER)??_(e.CHANGE_AUTHOR),_(e.BUILD_USER_EMAIL)??_(e.CHANGE_AUTHOR_EMAIL),"jenkins",_(e.BUILD_USER_ID));if(c)return c;let l=_(e.CIRCLE_USERNAME),u=D(l,null,"circleci",l);if(u)return u;let d=_(e.CODEBUILD_INITIATOR),g=D(d,null,"codebuild",d);if(g)return g;let f=D(_(e.DRONE_COMMIT_AUTHOR)??_(e.DRONE_COMMIT_AUTHOR_NAME),_(e.DRONE_COMMIT_AUTHOR_EMAIL),"drone",_(e.DRONE_COMMIT_AUTHOR));return f||(an(e.CLAUDE_CODE_REMOTE)||an(e.CURSOR_AGENT)?{git_user_name:null,git_user_email:null,platform_login:null,identity_source:"cloud"}:null)}function Ye(e){return!!((e.git_user_name??e.git_user_email)&&!ho(e.git_user_name,e.git_user_email))}function _(e){if(e===void 0)return null;let t=e.trim();return t.length>0?t:null}function an(e){if(e===void 0||e==="")return!1;let t=e.trim().toLowerCase();return t!=="0"&&t!=="false"&&t!=="no"}var go=new Set(["action@github.com","noreply@github.com","noreply@anthropic.com","cursoragent@cursor.com"]),_o=new Set(["github-actions","github actions","dependabot","renovate","cursoragent","cursor agent"]);function ho(e,t){let n=(e??"").trim().toLowerCase(),r=(t??"").trim().toLowerCase();if(!n&&!r)return!1;if(n.includes("[bot]")||_o.has(n)||r.includes("[bot]")||go.has(r))return!0;if(r.endsWith("@users.noreply.github.com")){let o=r.slice(0,r.indexOf("@")),s=o.includes("+")?o.slice(o.indexOf("+")+1):o;if(s.endsWith("bot")||s.includes("[bot]"))return!0}return!1}async function Eo(e,t=R,n=process.env){let r=await uo(e,t);if(Ye(r))return{...r,identity_source:"git_config"};let o=po(n);if(o&&Ye(o))return o;let s=mo(n);if(s&&(s.git_user_name||s.git_user_email||s.platform_login))return s;let i=await fo(e,t);return i&&Ye(i)?i:s||(r.git_user_name||r.git_user_email?{...r,identity_source:"git_config"}:o||i||{git_user_name:null,git_user_email:null,platform_login:null,identity_source:"git_config"})}async function ge(e){let{gitRoot:t,installationStorePath:n,forceResend:r}=e,o=e.exec??R,s=e.env??process.env,i=await Eo(t,o,s),a=co(i.git_user_name,i.git_user_email,i.identity_source,i.platform_login),l=(n?He(n):void 0)?.operator_identity_hash;if(!(r||l!==void 0&&l!==a||!l))return{commit:()=>{}};let f=n;return{operator:i,commit:()=>{f&&Xt(f,a,de())}}}function Xe(e){return e?!He(e)?.operator_identity_hash:!0}function cn(e){return!0}import{existsSync as $o,readFileSync as Go}from"node:fs";import{homedir as An}from"node:os";import{join as w}from"node:path";import{basename as Fo,join as J}from"node:path";import{existsSync as ln,readdirSync as So}from"node:fs";import{basename as yo,dirname as Io,relative as Ro}from"node:path";var _e=class{constructor(t){this.home=t}components=[];truncated=!1;pluginExpandRemaining;homeRel(t){let n=Ro(this.home,t).replace(/\\/g,"/");if(!n||n.startsWith("..")){let r=Io(t);return`external/${I(r)}/${yo(t)}`}return n}get atGlobalCap(){return this.truncated||this.components.length>=G}get pluginBudgetSpent(){return this.pluginExpandRemaining!==void 0&&this.pluginExpandRemaining<=0}readEntries(t){if(!ln(t))return[];try{return So(t,{withFileTypes:!0})}catch{return[]}}readJson(t,n){if(ln(t))return W(t,n)}push(t){return this.components.length>=G?(this.truncated=!0,!1):this.pluginExpandRemaining!==void 0&&this.pluginExpandRemaining<=0?!1:(this.pluginExpandRemaining!==void 0&&(this.pluginExpandRemaining-=1),this.components.push(t),!0)}withPluginExpandCap(t,n){let r=this.pluginExpandRemaining;this.pluginExpandRemaining=t;try{let o=n(),s=t-(this.pluginExpandRemaining??0);return{result:o,expanded:s}}finally{this.pluginExpandRemaining=r}}};import{existsSync as Ze,readFileSync as Co,statSync as To}from"node:fs";import{basename as dn,join as re,relative as pn}from"node:path";var Qe=2e4,Ao=4;function ko(e){return e.length<=Qe?e:`${e.slice(0,Qe-1)}\u2026`}function Oo(e){try{let t=Co(e),n=t.toString("utf8");return{hash:I(t),length:t.length,text:ko(n)}}catch{return null}}var un={HOOK:"EVENT",COMMAND:"EXPLICIT_INVOCATION",MEMORY:void 0,MCP_SERVER:void 0,PLUGIN:void 0,SKILL:"UNSPECIFIED",RULE:"UNSPECIFIED",SUBAGENT:"UNSPECIFIED"};function xo(e){return e in un?un[e]:"UNSPECIFIED"}function he(e,t){let n=Oo(t.absolutePath);if(!n)return!1;let r=t.name??dn(t.absolutePath).replace(/\.(md|mdc|toml)$/i,""),o={kind:t.kind,name:r,path:e.homeRel(t.absolutePath),text:n.text,content_hash:n.hash,content_length:n.length,origin:t.origin,enabled:t.enabled},s=xo(t.kind);return s&&(o.trigger=s),e.push(o)}function Uo(e,t,n){let r=pn(e,t).replace(/\\/g,"/");return!r||r.startsWith("..")?dn(t).replace(/\.(md|mdc|toml)$/i,""):n?r.replace(/\.(md|mdc|toml)$/i,""):r}function j(e,t){let{dir:n,kind:r,origin:o,enabled:s,nested:i,extensions:a}=t;qe(e,{walkRoot:n,currentDir:n,depth:0,kind:r,origin:o,enabled:s,nested:i,extensions:a})}function qe(e,t){let{walkRoot:n,currentDir:r,depth:o,kind:s,origin:i,enabled:a,nested:c,extensions:l}=t;if(!(o>Ao))for(let u of e.readEntries(r)){if(e.atGlobalCap){e.truncated=!0;return}if(e.pluginBudgetSpent)return;if(c){if(!u.isDirectory())continue;let f=re(r,u.name,c);if(Ze(f)){let h=pn(n,re(r,u.name)).replace(/\\/g,"/");he(e,{absolutePath:f,kind:s,origin:i,enabled:a,name:h||u.name});continue}qe(e,{walkRoot:n,currentDir:re(r,u.name),depth:o+1,kind:s,origin:i,enabled:a,nested:c,extensions:l});continue}if(u.isDirectory()){qe(e,{walkRoot:n,currentDir:re(r,u.name),depth:o+1,kind:s,origin:i,enabled:a,nested:c,extensions:l});continue}if(!u.isFile()||!l)continue;let d=u.name.toLowerCase();if(!l.some(f=>d.endsWith(f)))continue;let g=re(r,u.name);he(e,{absolutePath:g,kind:s,origin:i,enabled:a,name:Uo(n,g,!0)})}}function fn(e){for(let t of e)if(Ze(t))try{if(To(t).size>0)return t}catch{continue}return e.find(t=>Ze(t))}function bo(e){if(e.prompt||e.type==="prompt")return"prompt";let t=e.command??e.bash??e.powershell??"";return/\bnpx\b/i.test(t)?"npx":/\.(sh|bash|zsh|js|mjs|cjs|ts|py)(\s|$|"|')/i.test(t)||/^(\.\/|~\/|\/|[A-Za-z]:[\\/])/.test(t.trim())?"script":"inline"}function wo(e){return Array.isArray(e.hooks)&&e.hooks.length>0?e.hooks:[{type:e.type,command:e.command,bash:e.bash,powershell:e.powershell,prompt:e.prompt}]}function No(e,t,n,r){let o=e.homeRel(t);for(let[s,i]of Object.entries(n))if(!(!Array.isArray(i)||e.truncated))for(let a of i){if(!a||typeof a!="object"||e.truncated)continue;let c=a;for(let l of wo(c)){if(e.truncated)return;let u=l.command??l.bash??l.prompt??l.powershell??c.powershell??"",d=bo({type:l.type??c.type,command:l.command??c.command,bash:l.bash??c.bash,powershell:l.powershell??c.powershell,prompt:l.prompt??c.prompt}),g=typeof c.matcher=="string"?c.matcher:"",f=I(u),h=g?`${s}:${g}:${d}:${f}`:`${s}:${d}:${f}`,x=`${s}|${g}|${d}|${u}`;e.push({kind:"HOOK",name:h,path:o,content_hash:I(x),origin:r,enabled:!0,trigger:"EVENT",attributes:{event:s,...g?{matcher:g}:{},action_kind:d,action_hash:f}})}}}function oe(e,t,n){let r=e.readJson(t,{});!r?.hooks||typeof r.hooks!="object"||No(e,t,r.hooks,n)}var mn={claude:{skillRoots:[".claude/skills"],dirs:[{dir:".claude/agents",kind:"SUBAGENT",extensions:[".md"]},{dir:".claude/commands",kind:"COMMAND",extensions:[".md"]}],memory:[".claude/CLAUDE.md"],hooks:[".claude/settings.json"],mcpJson:[".claude.json"],plugins:"claude"},cursor:{skillRoots:[".cursor/skills",".cursor/skills-cursor"],dirs:[{dir:".cursor/agents",kind:"SUBAGENT",extensions:[".md"]},{dir:".cursor/commands",kind:"COMMAND",extensions:[".md"]},{dir:".cursor/rules",kind:"RULE",extensions:[".mdc",".md"]}],memory:[".cursor/AGENTS.md"],hooks:[".cursor/hooks.json"],mcpJson:[".cursor/mcp.json"],plugins:"cursor"},codex:{skillRoots:[".agents/skills",".codex/skills"],dirs:[{dir:".codex/agents",kind:"SUBAGENT",extensions:[".toml",".md"]},{dir:".codex/prompts",kind:"COMMAND",extensions:[".md"]}],memory:[".codex/AGENTS.override.md",".codex/AGENTS.md"],hooks:[".codex/hooks.json"],mcpToml:[".codex/config.toml"]}};import{existsSync as vo,readFileSync as Mo}from"node:fs";function Lo(e){if(!e||typeof e!="object"||Array.isArray(e))return"unknown";let t=e;return typeof t.type=="string"&&t.type.length>0?t.type:typeof t.url=="string"?"http":typeof t.command=="string"?"stdio":"unknown"}function gn(e,t,n){let o=e.readJson(t,{})?.mcpServers;if(!o||typeof o!="object")return;let s=e.homeRel(t);for(let[i,a]of Object.entries(o)){if(e.truncated)return;let c=Lo(a);e.push({kind:"MCP_SERVER",name:i,path:s,content_hash:I(`${i}|${c}`),origin:n,enabled:!0,attributes:{transport:c}})}}function _n(e,t,n){if(!vo(t))return;let r;try{r=Mo(t,"utf8")}catch{return}let o=e.homeRel(t),s=/^\[mcp_servers(?:\.(\w+)|\."([^"]+)"|\.'([^']+)')\]\s*$/gm,i;for(;(i=s.exec(r))!==null;){if(e.truncated)return;let a=i[1]??i[2]??i[3];if(!a)continue;let c=r.slice(i.index+i[0].length),l=c.search(/^\[/m),u=l===-1?c:c.slice(0,l),d="unknown";/^\s*url\s*=/m.test(u)?d="http":/^\s*command\s*=/m.test(u)&&(d="stdio"),e.push({kind:"MCP_SERVER",name:a,path:o,content_hash:I(`${a}|${d}`),origin:n,enabled:!0,attributes:{transport:d}})}}import{existsSync as Po,readdirSync as Do}from"node:fs";import{join as T}from"node:path";var hn=50;function et(e,t,n,r){if(!Po(t))return{componentCount:0,expandTruncated:!1};let o=e.components.length,{expanded:s}=e.withPluginExpandCap(hn,()=>{j(e,{dir:T(t,"skills"),kind:"SKILL",origin:n,enabled:r,nested:"SKILL.md"}),j(e,{dir:T(t,"commands"),kind:"COMMAND",origin:n,enabled:r,extensions:[".md"]}),j(e,{dir:T(t,"agents"),kind:"SUBAGENT",origin:n,enabled:r,extensions:[".md"]})});oe(e,T(t,"hooks","hooks.json"),n),oe(e,T(t,"hooks.json"),n);let i=e.components.length-o,a=s>=hn;return{componentCount:i,expandTruncated:a}}function tt(e,t){e.push({kind:"PLUGIN",name:t.pluginKey,path:t.rowPath,content_hash:t.contentHash,origin:"user",enabled:t.enabled,attributes:{...t.marketplace?{marketplace:t.marketplace}:{},...t.version?{version:t.version}:{},scope:t.scope,component_count:t.componentCount,...t.expandTruncated?{expand_truncated:!0}:{}}})}function En(e){let t=T(e.home,".claude/plugins/installed_plugins.json"),n=e.readJson(t,{});if(!n)return;let r=n.plugins??{},s=e.readJson(T(e.home,".claude/settings.json"),{})?.enabledPlugins??{},i=e.homeRel(t);for(let[a,c]of Object.entries(r)){if(e.truncated)return;let l=Array.isArray(c)?c:[c],u=l[0]??{},d=s[a]===!0,g=a.includes("@")?a.split("@").slice(1).join("@"):"",f=typeof u.version=="string"?u.version:"",h=typeof u.scope=="string"?u.scope:"user",x=`plugin:${a}`,v=0,C=!1;for(let U of l)if(typeof U.installPath=="string"&&U.installPath.length>0){let F=et(e,U.installPath,x,d);v+=F.componentCount,C=C||F.expandTruncated}tt(e,{pluginKey:a,rowPath:i,enabled:d,scope:h,version:f||void 0,marketplace:g||void 0,componentCount:v,expandTruncated:C,contentHash:I(`${a}|${f}|${h}|${d}|${v}`)})}}function Ho(e){let t=e,n="";try{let r=Do(e,{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>o.name);if(r.length===1&&r[0])t=T(e,r[0]),n=r[0];else if(r.length>1){let o=[...r].sort(),s=o[o.length-1];s&&(t=T(e,s),n=s)}}catch{}return{installPath:t,version:n}}function Sn(e){let t=[{base:T(e.home,".cursor/plugins/local"),scope:"local"},{base:T(e.home,".cursor/plugins/cache"),scope:"cache"}];for(let{base:n,scope:r}of t)if(!e.truncated)for(let o of e.readEntries(n)){if(!o.isDirectory()||e.truncated)continue;if(r==="local"){let i=o.name,a=T(n,o.name),c=`plugin:${i}`,{componentCount:l,expandTruncated:u}=et(e,a,c,!0);tt(e,{pluginKey:i,rowPath:e.homeRel(a),enabled:!0,scope:"local",componentCount:l,expandTruncated:u,contentHash:I(`${i}|local|${l}`)});continue}let s=o.name;for(let i of e.readEntries(T(n,s))){if(!i.isDirectory()||e.truncated)continue;let a=T(n,s,i.name),{installPath:c,version:l}=Ho(a),u=`${i.name}@${s}`,d=`plugin:${u}`,{componentCount:g,expandTruncated:f}=et(e,c,d,!0);tt(e,{pluginKey:u,rowPath:e.homeRel(c),enabled:!0,scope:"cache",version:l||void 0,marketplace:s,componentCount:g,expandTruncated:f,contentHash:I(`${u}|${l}|${g}`)})}}}function nt(e,t){let n=mn[e],r=new _e(t),o="user";if(!n)return{components:[],truncated:!1};for(let i of n.skillRoots)j(r,{dir:J(t,i),kind:"SKILL",origin:o,enabled:!0,nested:"SKILL.md"});for(let i of n.dirs)j(r,{dir:J(t,i.dir),kind:i.kind,origin:o,enabled:!0,extensions:i.extensions});let s=fn(n.memory.map(i=>J(t,i)));s&&he(r,{absolutePath:s,kind:"MEMORY",origin:o,enabled:!0,name:Fo(s)});for(let i of n.hooks)oe(r,J(t,i),o);for(let i of n.mcpJson??[])gn(r,J(t,i),o);for(let i of n.mcpToml??[])_n(r,J(t,i),o);return n.plugins==="claude"?En(r):n.plugins==="cursor"&&Sn(r),{components:r.components,truncated:r.truncated}}function rt(e,t,n={}){let r=n.truncated===!0,o=Je(e),s=new Set(e.map(u=>P(u.path,u.name)));if(n.forceFull===!0||t===void 0)return{hash:o,count:e.length,truncated:r,full:!0,upserts:e,removed:[],unchanged:!1};let a=[],c=t;for(let u of e){let d=P(u.path,u.name);c[d]!==u.content_hash&&a.push(u)}let l=[];if(!r){for(let u of Object.keys(c))if(!s.has(u)){let d=sn(u);d&&l.push(d)}}return{hash:o,count:e.length,truncated:r,full:!1,upserts:a,removed:l,unchanged:a.length===0&&l.length===0}}var In=3e5,Bo=new Set(["HOOK","MCP_SERVER","PLUGIN"]);function ot(e,t,n){let r=new Set(t.map(s=>P(s.path,s.name))),o=[];for(let s of e)s.text!==void 0&&(n.has(s.content_hash)||r.has(P(s.path,s.name))||o.push(s));return o}function st(e,t,n){let r=new Set(e);for(let s of t)r.add(s);let o=new Set(n.map(s=>s.content_hash));return[...r].filter(s=>o.has(s))}function yn(e){return Buffer.byteLength(JSON.stringify(e),"utf8")}function Rn(e){if(e.text===void 0)return e;let{text:t,...n}=e;return n}function it(e,t=In){let n=[],r=[];for(let u of e)Bo.has(u.kind)?n.push(u):r.push(u);r.sort((u,d)=>(u.text?.length??0)-(d.text?.length??0));let o=[...n,...r],s=[],i=2,a=0,c=0,l=[];for(let u of o){let d=s.length>0?1:0,g=yn(u)+d;if(i+g<=t){s.push(u),i+=g,u.text!==void 0&&l.push(u.content_hash);continue}if(u.text!==void 0){let f=Rn(u),h=yn(f)+d;if(i+h<=t){s.push(f),i+=h,a+=1;continue}}c+=1}return{components:s,textDeferredCount:a,droppedCount:c,textHashesSent:l}}function at(e,t){return t.size===0?e:e.map(n=>n.text===void 0||!t.has(n.content_hash)?n:Rn(n))}var Ko={claude:{skills:".claude/skills",subagents:".claude/agents",commands:".claude/commands",memory:".claude/CLAUDE.md",settings:".claude/settings.json"},cursor:{skills:[".cursor/skills",".cursor/skills-cursor"],subagents:".cursor/agents",commands:".cursor/commands",rules:".cursor/rules",mcp:".cursor/mcp.json"},codex:{skills:[".agents/skills",".codex/skills"],subagents:".codex/agents",commands:".codex/prompts",memory:".codex/AGENTS.md",settings:".codex/config.toml"}},jo=200,Cn=200,Vo=["allow","deny","ask"],zo=/(?<=^|[\s(,=:])(?:~|[A-Za-z]:)?[\\/][^\s,)]+/g,ct="<path>",Wo=new RegExp(`${ct}(?:\\s+[A-Za-z.][^\\s,)]*[\\\\/][^\\s,)]*)+`,"g");function Jo(e){let t=e.replace(zo,ct).replace(Wo,ct);return t.length>Cn?`${t.slice(0,Cn)}...`:t}function Tn(e){let t=W(e,{}),n=[];for(let r of Vo)for(let o of t.permissions?.[r]??[])typeof o=="string"&&o.length>0&&n.push({key:Jo(o),mode:r});return{model:t.model??"",permissionKeys:n}}var Yo=10,Xo=840*60*1e3,Zo="self-config-cache.json";function lt(){return E("EV_AI_HOOK_USER_SPEC")?.toLowerCase()==="off"}function Qo(e,t=Date.now()){return e===void 0||!Number.isFinite(e)?!0:t-e>=Xo}var qo={claude:["claude"],cursor:["agent","cursor-agent"],codex:["codex"]};async function es(e,t=R){let n=qo[e];if(!n||n.length===0)return null;let r=async o=>{let s=n[o];if(s===void 0)return null;let a=((await t(s,["--version"],2e3)).split(`
|
|
10
|
-
`)
|
|
11
|
-
|
|
12
|
-
`)}catch(n){let r=n instanceof Error?n.message:String(n);m(`WARN: self-config cache write failed open: ${r}`)}}function ss(e,t,n,r){let o={...e,send_count:n};for(let s of Object.keys(t)){let i=t[s];i.entries!==void 0&&(o[s]=i.hash)}return r&&(o.user_spec_collected_at_ms=r.collectedAtMs,r.included&&(o.user_spec=r.hash,o.user_spec_components=r.componentHashes),o.user_spec_text_hashes=r.textHashes),o}async function kn(e,t=process.cwd(),n=An(),r={}){let o=e==="claude",s=r.gitRoot??t,i=await es(e),a="",c=[];if(o){let b=Tn(w(n,".claude/settings.json")),M=Tn(w(t,".claude/settings.local.json"));a=M.model||b.model,c=[...b.permissionKeys,...M.permissionKeys].slice(0,jo)}let l=Ko[e]??{},u={present:!1,size:0},d=b=>{let M=Array.isArray(b)?b:b?[b]:[],S=[],H=!1;for(let Ae of M){let k=q(w(n,Ae));if(S=S.concat(k.entries),H=H||k.truncated,S.length>=G){S=S.slice(0,G),H=!0;break}}return{entries:S,truncated:H}},g=ts(n),f=rs(g),h=f[e]??{},x=(h.send_count??0)+1,v=x>0&&x%Yo===0,C=b=>v?void 0:h[b],U=d(l.skills),F=l.subagents?q(w(n,l.subagents)):{entries:[],truncated:!1},Te=l.commands?q(w(n,l.commands)):{entries:[],truncated:!1},yt=l.rules?q(w(n,l.rules)):{entries:[],truncated:!1},Z={skills:Ee(U.entries,C("skills"),U.truncated),subagents:Ee(F.entries,C("subagents"),F.truncated),commands:Ee(Te.entries,C("commands"),Te.truncated),rules:Ee(yt.entries,C("rules"),yt.truncated)},A={runner_platform:e,config_scope:"user",cli_version:i,claude_version:o?i:null,model:o&&a||null,permission_keys:c,user_scope:{skills:Z.skills,subagents:Z.subagents,commands:Z.commands,rules:Z.rules,memory:l.memory?ee(w(n,l.memory)):u,settings:l.settings?ee(w(n,l.settings)):u,mcp:l.mcp?ee(w(n,l.mcp)):u},local_settings:o?ee(w(t,".claude/settings.local.json")):u},It=null,Rt=()=>{},Ct=r.nowMs??Date.now();if(!lt()&&Qo(h.user_spec_collected_at_ms,Ct)){let b=h.user_spec_collected_at_ms!==void 0,M=nt(e,n),S=rt(M.components,h.user_spec_components,{forceFull:!h.user_spec_components,truncated:M.truncated}),H=new Set(h.user_spec_text_hashes??[]),Ae=ot(M.components,S.upserts,H),k=it(at([...S.upserts,...Ae],H));A.user_spec_hash=S.hash,A.user_spec_count=S.count,A.user_spec_truncated=S.truncated||k.droppedCount>0,(k.components.length>0||S.removed.length>0||S.full)&&(S.full&&(A.user_spec_full=!0),k.components.length>0&&(A.user_spec=k.components),S.removed.length>0&&!A.user_spec_truncated&&(A.user_spec_removed=S.removed),k.textDeferredCount>0&&(A.user_spec_text_deferred=k.textDeferredCount));let ke=S.full?{}:{...h.user_spec_components??{}};if(!A.user_spec_truncated)for(let z of S.removed)delete ke[P(z.path,z.name)];for(let z of k.components)ke[P(z.path,z.name)]=z.content_hash;It={hash:S.hash,componentHashes:ke,textHashes:st(H,k.textHashesSent,M.components),included:k.components.length>0||S.removed.length>0&&!A.user_spec_truncated||S.full,collectedAtMs:Ct};let Oe=await ge({gitRoot:s,installationStorePath:r.installationStorePath,forceResend:b});Oe.operator&&(A.operator=Oe.operator),Rt=Oe.commit}let ur=ss(h,Z,x,It);return{config:A,commit:()=>{f[e]=ur,os(g,f),Rt()}}}function Y(e,t,n){let r={installation_id:n.installationId};return n.platformAgentId&&(r.platform_agent_id=n.platformAgentId),n.sessionId&&(r.session_id=n.sessionId),n.turnId&&(r.turn_id=n.turnId),{schema_version:2,event:e,timestamp:de(),session_id:n.sessionId||null,turn_id:n.turnId||null,installation_id:n.installationId,platform:n.runnerPlatform,platform_agent_id:n.platformAgentId||null,runner_event:n.runnerEvent||null,agent_hook_version:be,host_arch:process.arch,node_version:process.version,correlation:r,payload:t}}import{existsSync as zn}from"node:fs";import{spawn as Wn}from"node:child_process";import{basename as Ns}from"node:path";import{fileURLToPath as vs}from"node:url";var is=new Set(["localhost","127.0.0.1","[::1]","::1"]),On=/^[A-Za-z0-9._~-]+$/;function xn(e){for(let t=0;t<e.length;t++){let n=e.charCodeAt(t);if(n<=32||n===127||n===39)return!0}return!1}function Se(e){try{let t=new URL(e);return t.protocol==="https:"?!0:t.protocol==="http:"?is.has(t.hostname):!1}catch{return!1}}function Un(e){let t;try{t=new URL(e)}catch{return`invalid URL (got: ${e})`}if(!Se(e))return`must be https (or http on localhost / 127.0.0.1 / ::1) (got: ${e})`;let n=as(e);if(!n)return`must end with /{orgToken}/hook (got: ${e})`;if(!On.test(n))return`org token must match ${On.source} (got: ${n})`;if(xn(e))return`must not contain whitespace, control characters, or single quotes (got: ${e})`;if(xn(t.pathname))return`pathname must not contain whitespace, control characters, or single quotes (got: ${e})`}function bn(e){return new URL(e).toString()}function as(e){try{let n=new URL(e).pathname.split("/").filter(r=>r.length>0);if(n.length>=2&&n[n.length-1]==="hook"){let r=n[n.length-2];return r.length>0?r:void 0}return}catch{return}}function dt(e){try{let t=new URL(e),n=t.pathname.split("/").filter(r=>r.length>0);return n.length>=2&&n[n.length-1]==="hook"&&(n[n.length-2]="***",t.pathname=`/${n.join("/")}`),t.toString()}catch{return"<invalid-url>"}}function wn(e){if(e.collector_url)return e.collector_url;let t=e.repo_ingest_token?.trim();return t?le(t):""}var Nn=/(?:^|\/|[\s"'=(])(?:\.cursor\/|\.claude\/|\.agents\/)skills(?:-cursor)?\/([^/]+)\/SKILL\.md/i,vn=/(?:^|\/|[\s"'=(])\.codex\/commands\/([^/]+)\.md\b/i,cs=/(?:^|\s)\/([a-z][a-z0-9-]{1,63})\b/gi,ls=new Set(["applications","app","bin","boot","data","dev","etc","home","lib","media","mnt","node_modules","opt","pkg","private","proc","projects","repos","run","sbin","src","srv","sys","tmp","usr","users","var","volumes","workspace","workspaces"]),us=new Set(["read","read_file","view"]),ds=new Set(["bash","shell","zsh"]);function ps(e){let t=e.replace(/\\/g,"/");return Nn.exec(t)?.[1]??null}function fs(e){let t=e.replace(/\\/g,"/"),r=vn.exec(t)?.[1];return r?r.toLowerCase():null}function ms(e){return ps(e)??fs(e)}function gs(e){for(let t of["path","file_path","target_file"]){let n=e[t];if(typeof n=="string"&&n.length>0)return n}return null}function Mn(e){if(typeof e=="string")try{let t=JSON.parse(e);return Mn(t)}catch{return null}return!e||typeof e!="object"?null:gs(e)}function _s(e){if(!e||typeof e!="object")return null;let t=e.command;return typeof t=="string"&&t.length>0?t:null}function hs(e){let t=e.replace(/\\/g,"/"),n=Nn.exec(t);if(n?.[1])return n[1];let o=vn.exec(t)?.[1];return o?o.toLowerCase():null}function Es(e){return typeof e.tool_name=="string"?e.tool_name:typeof e.tool=="string"?e.tool:""}function Ln(e){let t=Es(e).toLowerCase();if(us.has(t)){let n=Mn(e.tool_input);return n?ms(n):null}if(ds.has(t)){let n=_s(e.tool_input);return n?hs(n):null}return null}function Ss(e){let t=new Set,n=[];for(let r of e.matchAll(cs)){let o=r[1]?.toLowerCase();!o||t.has(o)||ls.has(o)||(t.add(o),n.push(o))}return n}function ys(e){return Q(e.prompt)}function Pn(e){let t=p(e,"command_name");if(t){let r=p(e,"expansion_type");if(r&&r!=="slash_command")return[];let o=t.replace(/^\//,"").toLowerCase();return o?[o]:[]}let n=ys(e);return n?Ss(n):[]}function pt(e){return e!==void 0&&bt.includes(e)}function ye(e,t){let n=e[t+1];return n&&!n.startsWith("--")?{value:n,next:t+1}:{next:t}}function Ie(e){let t,n,r,o,s;for(let i=0;i<e.length;i++){let a=e[i];if(a!==void 0){if(a==="--runner"){let c=ye(e,i);t=c.value,i=c.next;continue}if(a.startsWith("--runner=")){t=a.slice(9);continue}if(a==="--url"){let c=ye(e,i);c.value&&(r=c.value),i=c.next;continue}if(a.startsWith("--url=")){r=a.slice(6);continue}if(a==="--token"){let c=ye(e,i);c.value&&(o=c.value),i=c.next;continue}if(a.startsWith("--token=")){o=a.slice(8);continue}if(a==="--base-url"){let c=ye(e,i);c.value&&(s=c.value),i=c.next;continue}if(a.startsWith("--base-url=")){s=a.slice(11);continue}!a.startsWith("-")&&n===void 0&&(n=a)}}return{runner:pt(t)?t:void 0,event:n,collectorUrl:r,orgToken:o,baseUrl:s}}function ft(e){let t=e.collectorUrl?.trim(),n;if(t)n=t;else{let o=e.orgToken?.trim();o&&(n=le(o,e.baseUrl?.trim()??void 0))}if(!n)return;let r=Un(n);if(r){m(`WARN: ignoring --url/--token collector override: ${r}`);return}return bn(n)}function Dn(e,t){if(p(e,"conversation_id"))return!0;if(t==="")return!1;let n=t[0];return n?.toLowerCase()===n}function Is(){return!!(E("CURSOR_VERSION")??E("CURSOR_PROJECT_DIR"))}function mt(e,t,n){return e!=="claude"&&e!=="codex"?!1:Dn(t,n)?!0:Is()}function gt(e,t,n,r){if(Dn(e,t))return"cursor";if(pt(r))return r;let o=p(e,"conversation_id"),s=p(e,"turn_id"),i=p(e,"session_id"),a=t.toLowerCase(),c="unknown";return o||t===a&&t!==""?c="cursor":s?c="codex":(i||a==="sessionstart"||a==="sessionend"||a==="stop"||a==="stopfailure"||a==="pretooluse"||a==="posttooluse"||a==="posttoolusefailure"||a==="permissiondenied"||a==="subagentstart"||a==="subagentstop"||a==="userpromptexpansion")&&(c="claude"),pt(n)&&(c=n),c}function Re(e,t){let n=e.toLowerCase();return n==="sessionend"||n==="stopfailure"||n==="subagentstop"?!0:n==="stop"&&t==="codex"}function Rs(e){switch(e){case"sessionstart":return"session_start";case"stop":case"sessionend":case"stopfailure":return"session_end";case"pretooluse":case"posttooluse":case"posttoolusefailure":case"permissiondenied":case"beforemcpexecution":case"beforeshellexecution":case"afterfileedit":case"subagentstart":case"subagentstop":return"tool_invoked";case"beforesubmitprompt":case"userpromptexpansion":case"userpromptsubmit":return"skill_invoked";default:return""}}function Hn(e){let t=e.toLowerCase();return t==="posttooluse"?!0:t==="posttoolusefailure"||t==="permissiondenied"?!1:null}function Fn(e,t,n){let r=p(e,"session_id")||p(e,"conversation_id"),o=p(e,"prompt.id")||p(e,"prompt_id")||p(e,"generation_id")||p(e,"turn_id"),s=p(e,"hook_event_name")||p(e,"event"),i=p(e,"source"),a=gt(e,s,t,n);return{sessionId:r,turnId:o,runnerEvent:s,hookSource:i,runnerPlatform:a}}var Cs=["session_start","session_end","tool_invoked","skill_invoked"];function Ts(e){return Cs.includes(e)}function Bn(e,t){return e&&Ts(e)?e:Rs(t.toLowerCase())}function $n(e){let t=p(e,"tool_name")||p(e,"tool")||null,n=e.tool_input,o=(n&&typeof n=="object"?Q(n.skill)||Q(n.skill_name):"")||p(e,"skill_name")||null;return o??=Ln(e),{toolName:t,skillName:o}}var As=/^[A-Za-z][A-Za-z0-9_.:-]{0,63}$/;function Gn(e){for(let t of["subagent_type","agent_type"]){let n=p(e,t);if(n&&As.test(n))return n}return null}function Kn(e){let t=$(e,"duration_ms");if(typeof t=="number")return t;let n=$(e,"duration");return typeof n=="number"?n:null}var ks="error",Os="interrupted",xs="permission_denied",Us=/^[A-Za-z][A-Za-z0-9_.-]{0,63}$/;function _t(e){return Us.test(e)?e:null}function bs(e){for(let t of["failure_type","error_type"]){let n=_t(p(e,t));if(n)return n}return null}function jn(e,t){return $(e,"is_interrupt")===!0?Os:t.toLowerCase()==="permissiondenied"?xs:bs(e)??ks}function ws(e,t){let n=null;for(let r of t)r&&(e===r||e.startsWith(`${r}_`)||e.startsWith(`${r}-`))&&(n===null||r.length>n.length)&&(n=r);return n}function Vn(e,t=[]){if(!e)return{mcpServer:null,mcpTool:null};let n=/^mcp__(.+?)__(.+)$/i.exec(e);if(n?.[1]&&n[2])return{mcpServer:n[1],mcpTool:n[2]};if(/^MCP:/i.test(e)){let r=e.slice(4);if(!r)return{mcpServer:null,mcpTool:null};let o=r.indexOf(":");return o>0?{mcpServer:r.slice(0,o),mcpTool:r.slice(o+1)||null}:{mcpServer:ws(r,t),mcpTool:r}}return{mcpServer:null,mcpTool:null}}var ht="__post",Ce="__work";function Ms(e,t){let n=e.payload,r=n&&typeof n=="object"&&!Array.isArray(n)?Object.keys(n):[],o=e.correlation&&typeof e.correlation=="object"?Object.keys(e.correlation):[];return JSON.stringify({event:e.event,schema_version:e.schema_version,agent_hook_version:e.agent_hook_version,host_arch:e.host_arch,node_version:e.node_version,build_ms:e.build_ms,body_bytes:t,correlation_keys:o,payload_keys:r})}function Jn(e){switch(e){case"session_start":return At;case"session_end":return kt;case"tool_invoked":case"skill_invoked":return xe;default:return xe}}function Ls(e,t,n){return`${JSON.stringify({url:e,timeoutMs:t})}
|
|
13
|
-
${
|
|
14
|
-
`);
|
|
15
|
-
`,c=E("EV_AI_HOOK_DEBUG");c==="full"?m(`DEBUG envelope=${JSON.stringify(i)}`):c==="1"&&m(`DEBUG summary=${Ms(i,Buffer.byteLength(a,"utf8"))}`);let l=process.argv.includes(Ce),u=E("EV_AI_HOOK_SYNC")==="1";return Re(n.runnerEvent,n.runnerPlatform)||l||u?Hs(e,a,o):(await Fs(e,a,o),!1)}import{relative as Bs,resolve as Et,sep as qn}from"node:path";var $s=["session_id","conversation_id","turn_id","generation_id","prompt.id","prompt_id","hook_event_name","event","source","status","stop_reason","reason","tool_name","tool","tool_use_id","skill_name","command_name","expansion_type","command_source","permission_mode","model","model_id","agent_id","agent_type","subagent_id","subagent_type","subagent_model","is_parallel_worker","effort","effort.level","duration_ms","duration","failure_type","is_interrupt"];function Gs(e){return e.capture_hook_input==="full"?!0:e.capture_hook_input==="allowlist"?!1:E("EV_AI_HOOK_CAPTURE_FULL_INPUT")==="1"}function Ks(e){let t={};for(let n of $s){let r=$(e,n);r!==void 0&&(t[n]=r)}return t}function js(e,t){if(typeof e!="string"||e.length===0||!t)return null;let n=Et(e),r=Et(t),o=Bs(r,n);return!o||o==="."?".":o.startsWith(`..${qn}`)||o===".."||Et(r,o)!==n?null:o.split(qn).join("/")}function er(e,t){let n=JSON.stringify(e),r=Buffer.byteLength(n,"utf8");if(r<=t)return e;let o=Object.entries(e).filter(([i,a])=>!i.startsWith("_")&&(typeof a=="string"||typeof a=="number"||typeof a=="boolean")).sort((i,a)=>Buffer.byteLength(JSON.stringify(i[1]),"utf8")-Buffer.byteLength(JSON.stringify(a[1]),"utf8")),s={_truncated:!0,_original_bytes:r};for(let[i,a]of o){let c={...s,[i]:a};if(Buffer.byteLength(JSON.stringify(c),"utf8")>t)break;s[i]=a}return s}function se(e,t,n={}){let r=n.gitRoot!==void 0?js(e.cwd,n.gitRoot):null;if(Gs(t)){let s={...e};return delete s.cwd,delete s.transcript_path,r!==null&&(s.cwd_relative=r),er(s,Ut)}let o=Ks(e);return r!==null&&(o.cwd_relative=r),er(o,xt)}import{createReadStream as Vs}from"node:fs";import{stat as zs}from"node:fs/promises";import{basename as Ws,resolve as Js}from"node:path";import{createInterface as Ys}from"node:readline";var Xs=1024*1024;function Zs(e){let t=e.replace(/\\/g,"/");return t.includes("/.claude/projects/")&&Ws(t).endsWith(".jsonl")}async function tr(e){if(!e||!Zs(e))return null;try{let t=Js(e),n=await zs(t);if(!n.isFile())return null;let r=Math.max(0,n.size-Xs),o=[],s=Ys({input:Vs(t,{encoding:"utf8",start:r}),crlfDelay:1/0});for await(let i of s)i.length!==0&&o.push(i);r>0&&o.length>0&&o.shift();for(let i=o.length-1;i>=0;i--){let a=o[i];if(a)try{let c=JSON.parse(a);if(c.type!=="assistant")continue;let l=c.message;if(!l||typeof l!="object")continue;let u=l.model;if(typeof u=="string"&&u.length>0)return u}catch{continue}}return null}catch{return null}}function ae(e){return{sessionId:e.sessionId,turnId:e.turnId,installationId:e.manifest.installationId,runnerPlatform:e.runnerPlatform,platformAgentId:e.platformAgentId,runnerEvent:e.runnerEvent}}function Qs(...e){for(let t of e)if(t)return t;return null}function N(e,t,n){if(e.status==="fulfilled")return e.value;let r=e.reason instanceof Error?e.reason.message:String(e.reason);return m(`WARN: ${n} failed open: ${r}`),t}function qs(e){let t={present:!1,size:0},n={hash:"",count:0};return{config:{runner_platform:e,config_scope:"user",cli_version:null,claude_version:null,model:null,permission_keys:[],user_scope:{skills:n,subagents:n,commands:n,rules:n,memory:t,settings:t,mcp:t},local_settings:t},commit:()=>{}}}function ei(e,t){return{runner_platform:e,config_scope:"user",...t?{operator:t}:{}}}var V=new Set,ie=null;async function nr(e){if(lt())return;let t=e.manifest.installationId,n=e.manifest.installationStorePath;if(V.has(t))return;if(!Xe(n)){V.add(t);return}let r=Fe();if(cn(r)){if(ie){await ie;return}ie=(async()=>{if(V.has(t)||!Xe(n)){V.add(t);return}if(!Zt(n)){V.add(t);return}let o=!1;try{let s=Date.now(),{gitRoot:i}=e.manifest,a=String(e.runnerPlatform),[c,l,u,d,g]=await Promise.allSettled([ne(i),Be(),Ke(r),$e(),ge({gitRoot:i,installationStorePath:n,forceResend:!1})]),f=N(c,null,"gitSnapshot"),h=N(l,"","detectVirt"),x=N(u,null,"probeCloud"),v=N(d,{},"hostEnv"),C=N(g,{commit:()=>{}},"resolveOperatorForSend");await ce(e,i,f);let U={identity:{host:Ge(),context:r,virt:h||null,cloud:x,git:f},host_env:v,env_vars:We(),self_config:ei(a,C.operator),run_meta:{trigger:"cloud_identity_bootstrap"}};o=!!await X("session_start",U,ae(e),Y,e.manifest.collectorUrl,s),o&&(C.commit(),V.add(t))}finally{Qt(n)}})().finally(()=>{ie=null}),await ie}}async function ce(e,t,n){try{let r=n===void 0?await ne(t):n;e.platformAgentId=await rn(e.manifest.manifest,e.platformAgentId,String(e.runnerPlatform),t,r,e.manifest.installationStorePath,e.manifest.repoKey)}catch(r){let o=r instanceof Error?r.message:String(r);m(`WARN: derivePlatformAgentId failed open: ${o}`)}}async function ti(e){let t=Date.now(),{gitRoot:n}=e.manifest,r=Fe(),o=String(e.runnerPlatform),[s,i,a,c,l,u]=await Promise.allSettled([ne(n),Be(),Ke(r),$e(),ze(e.manifest.manifest,n,o),kn(o,n,void 0,{installationStorePath:e.manifest.installationStorePath,gitRoot:n})]),d=N(s,null,"gitSnapshot"),g=N(i,"","detectVirt"),f=N(a,null,"probeCloud"),h=N(c,{},"hostEnv"),x=N(l,[],"mcpDeclared"),v=N(u,qs(o),"selfConfig"),C=v.config;await ce(e,n,d);let U=p(e.hookInput,"model");U&&(C.model=U);let F={identity:{host:Ge(),context:r,virt:g||null,cloud:f,git:d},host_env:h,env_vars:We(),mcp:{declared:x},self_config:C,run_meta:{trigger:e.hookSource||"startup"},hook_input:se(e.hookInput,e.manifest.manifest,{gitRoot:n})};await X("session_start",F,ae(e),Y,e.manifest.collectorUrl,t)&&(v.commit(),V.add(e.manifest.installationId))}async function ni(e){let t=Date.now(),{gitRoot:n}=e.manifest;await ce(e,n);let r=Qs(p(e.hookInput,"status"),p(e.hookInput,"stop_reason"),p(e.hookInput,"reason"),_t(p(e.hookInput,"error"))),o=e.runnerPlatform==="claude"?await tr(p(e.hookInput,"transcript_path")):null,s=se(e.hookInput,e.manifest.manifest,{gitRoot:n});o&&(s.model=o),await X("session_end",{status:r,...o?{model:o}:{},hook_input:s},ae(e),Y,e.manifest.collectorUrl,t)}async function ri(e){let t=Date.now(),n=Pn(e.hookInput);if(n.length===0)return;await nr(e);let{gitRoot:r}=e.manifest;await ce(e,r);let o=se(e.hookInput,e.manifest.manifest,{gitRoot:r}),s=ae(e);await Promise.all(n.map(i=>X("tool_invoked",{tool_name:"Skill",skill_name:i,success:null,duration_ms:null,hook_input:o},s,Y,e.manifest.collectorUrl,t)))}async function oi(e){let t=Date.now();await nr(e);let{gitRoot:n}=e.manifest;await ce(e,n);let{toolName:r,skillName:o}=$n(e.hookInput),s=Kn(e.hookInput),i=Hn(e.runnerEvent),a=i===!1?jn(e.hookInput,e.runnerEvent):null,c=await ze(e.manifest.manifest,e.manifest.gitRoot,String(e.runnerPlatform)).catch(()=>[]),{mcpServer:l,mcpTool:u}=Vn(r,c.map(g=>g.name)),d=Gn(e.hookInput);await X("tool_invoked",{tool_name:r,skill_name:o,success:i,duration_ms:s,...a?{failure_reason:a}:{},...l?{mcp_server:l}:{},...u?{mcp_tool:u}:{},...d?{subagent_type:d}:{},hook_input:se(e.hookInput,e.manifest.manifest,{gitRoot:n})},ae(e),Y,e.manifest.collectorUrl,t)}async function rr(e){switch(e.internalEvent){case"session_start":await ti(e);return;case"session_end":await ni(e);return;case"skill_invoked":await ri(e);return;case"tool_invoked":await oi(e);return;default:return}}function or(e){return e!=="session_start"&&e!=="session_end"&&e!=="tool_invoked"&&e!=="skill_invoked"&&e!==""}import{existsSync as St,readFileSync as si}from"node:fs";import{dirname as ii,join as sr,relative as ai}from"node:path";var ir=[Tt,".cursor/ev-ai-runtime-report.json",".codex/ev-ai-runtime-report.json"];async function ci(e=process.cwd(),t){let n=E("EV_AI_HOOK_MANIFEST");if(n&&St(n))return n;let r=t??await pe(e);for(let o of ir){let s=sr(r,o);if(St(s))return s}for(let o of ir){let s=sr(e,o);if(St(s))return s}}async function li(e,t){let n=t??await pe(ii(e)),r=ai(n,e),o=await L("git",["ls-files","--error-unmatch",r],2e3,{cwd:n});return o.ok?!0:o.code===1?!1:(m(`WARN: git ls-files failed for manifest ${e} (code=${String(o.code)}); treating as tracked`),!0)}function ui(e){let t=si(e,"utf8");return O(t,{})}function di(){return{schema_version:2,mcp_servers:[]}}async function ar(e=process.cwd()){let t=await pe(e),n=await ci(e,t),r=n?ui(n):di();delete r.installation_id;let o=n?await li(n,t):!1;r.capture_hook_input==="full"&&n&&o&&(m(`WARN: ignoring capture_hook_input=full in git-tracked manifest ${n}; use EV_AI_HOOK_CAPTURE_FULL_INPUT=1 or an untracked operator manifest`),delete r.capture_hook_input);let{installationId:s,storePath:i,repoKey:a}=await nn(t);return{manifestPath:n??i,manifest:r,installationId:s,installationStorePath:i,repoKey:a,collectorUrl:wn(r),platformAgentId:r.platform_agent_id??"",gitRoot:t}}async function cr(e,t,n,r){let o=t??await ve(Ue),s=O(o,{}),i=await ar();if(!i)return;r&&(i.collectorUrl=r);let a=Fn(s,i.manifest.platform,n),c=Bn(e,a.runnerEvent);if(!c){m(`WARN: unknown hook event '${a.runnerEvent}'; skipping telemetry`);return}let l={hookInput:s,sessionId:a.sessionId,turnId:a.turnId,runnerEvent:a.runnerEvent,runnerPlatform:a.runnerPlatform,hookSource:a.hookSource,internalEvent:c,manifest:i,platformAgentId:i.platformAgentId};if(or(c)){m(`WARN: unsupported internal event '${c}'`);return}await rr(l)}function pi(e,t){if(E("EV_AI_HOOK_SYNC")==="1")return!0;let n=Ie(e),r=O(t,{}),o=n.event??(p(r,"hook_event_name")||p(r,"event")),s=gt(r,o,void 0,n.runner);return Re(o,s)}async function lr(e=process.argv.slice(2)){if(e[0]===ht){try{await Xn(Ne)}catch{}return 0}if(e[0]===Ce){try{let t=Ie(e.slice(1)),n=await Ne(),r=O(n,{}),o=t.event??(p(r,"hook_event_name")||p(r,"event"));if(mt(t.runner,r,o))return 0;await cr(t.event,n,t.runner,ft(t))}catch(t){let n=t instanceof Error?t.message:String(t);m(`WARN: detached work failed open: ${n}`)}return 0}try{let t=await ve(Ue),n=Ie(e),r=ft(n),o=O(t,{}),s=n.event??(p(o,"hook_event_name")||p(o,"event"));if(mt(n.runner,o,s))return 0;pi(e,t)?await cr(n.event,t,n.runner,r):await Qn(t,e)}catch(t){let n=t instanceof Error?t.message:String(t);m(`WARN: hook failed open: ${n}`)}finally{Dt()}return 0}lr().then(e=>{process.exit(e)}).catch(e=>{let t=e instanceof Error?e.message:String(e);process.stderr.write(`[ev-ai-agent-hook] ${t}
|
|
1
|
+
import { createRequire as __createRequire } from 'node:module';
|
|
2
|
+
const require = __createRequire(import.meta.url);
|
|
3
|
+
|
|
4
|
+
var Gr=Object.create;var Ft=Object.defineProperty;var jr=Object.getOwnPropertyDescriptor;var Vr=Object.getOwnPropertyNames;var zr=Object.getPrototypeOf,Jr=Object.prototype.hasOwnProperty;var Bt=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var Wr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Yr=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Vr(t))!Jr.call(e,o)&&o!==n&&Ft(e,o,{get:()=>t[o],enumerable:!(r=jr(t,o))||r.enumerable});return e};var Xr=(e,t,n)=>(n=e!=null?Gr(zr(e)):{},Yr(t||!e||!e.__esModule?Ft(n,"default",{value:e,enumerable:!0}):n,e));var Qn=Wr(H=>{"use strict";Object.defineProperty(H,"__esModule",{value:!0});H.ComponentKind=void 0;H.normalizeRepositoryRelativePath=Zn;H.nativeKeyForSkillPath=Bs;H.serializeComponentIdentity=qn;H.buildComponentReference=Ks;H.validateComponentReference=Gs;var Ls=Bt("node:crypto"),Ms=Bt("node:path"),Ds="cmp1_",Hs=/^cmp1_[A-Za-z0-9_-]{43}$/,Fs=["/skills/","/skills-cursor/"];H.ComponentKind={SKILL:"SKILL",INTERFACE:"INTERFACE"};function Ne(e,t){if(e.length===0)throw new Error(`${t} is required`);return e}function Zn(e){let t=e.replaceAll("\\","/");if(t.startsWith("/")||/^[A-Za-z]:\//.test(t))throw new Error("sourcePath must be repository-relative");let n=Ms.posix.normalize(t).replace(/^\.\//,"");if(n==="."||n===".."||n.startsWith("../"))throw new Error("sourcePath must be repository-relative");return Ne(n,"sourcePath")}function Bs(e){let t=e.replaceAll("\\","/");for(let n of Fs){let r=t.split(n)[1]?.split("/")[0];if(r&&r.length>0)return r}return null}function $s(e){return`${Buffer.byteLength(e,"utf8")}:${e}`}function qn(e){let t=[Ne(e.installationRootExternalKey,"installationRootExternalKey"),Ne(e.installableKind,"installableKind"),Zn(e.sourcePath),Ne(e.nativeKey,"nativeKey")];return Buffer.from(`1|${t.map($s).join("|")}`,"utf8")}function Ks(e){let t=(0,Ls.createHash)("sha256").update(qn(e)).digest("base64url");return`${Ds}${t}`}function Gs(e){return Hs.test(e)}});var Zr="https://hooks.ev-ai.ai";function Ie(e,t=Zr){let n=t.replace(/\/+$/,""),r=e.trim();return`${n}/${r}/hook`}var $t=".claude/ev-ai-runtime-report.json";var Re="ev-ai-agent-hook";var ja=`current/${Re}`,Va=`.ev-ai/agent-hook/${Re}`,Kt=5e3,Gt=5e3,Be=3e3;var $e=3e3,jt=1500,Vt=4*1024,zt=32*1024,qr=4*1024,Ke="1.0.8",za=`@ev-ai/agent-hook@${Ke}`;var Jt=["claude","cursor","codex"];import{createHash as _s}from"node:crypto";import{existsSync as hs,mkdirSync as Es,readdirSync as Ss,readFileSync as Gn,unlinkSync as jn,writeFileSync as Is}from"node:fs";import{homedir as Vn}from"node:os";import{join as ct}from"node:path";import{createHash as cn,randomBytes as yo}from"node:crypto";import{existsSync as ln,mkdirSync as qe,readFileSync as un,unlinkSync as dn,writeFileSync as fn}from"node:fs";import{homedir as Qe}from"node:os";import{dirname as Ce,join as et,resolve as Co}from"node:path";var Qr=new Set(["action@github.com","noreply@github.com","noreply@anthropic.com","cursoragent@cursor.com"]),eo=new Set(["github-actions","github actions","dependabot","renovate","cursoragent","cursor agent"]);function V(e,t){let n=(e??"").trim().toLowerCase(),r=(t??"").trim().toLowerCase();if(!n&&!r)return!1;if(n.includes("[bot]")||eo.has(n)||r.includes("[bot]")||Qr.has(r))return!0;if(r.endsWith("@users.noreply.github.com")){let o=r.slice(0,r.indexOf("@")),s=o.includes("+")?o.slice(o.indexOf("+")+1):o;if(s.endsWith("bot")||s.includes("[bot]"))return!0}return!1}import{existsSync as co,readFileSync as lo}from"node:fs";import{hostname as en,userInfo as uo}from"node:os";import{randomBytes as to}from"node:crypto";import{existsSync as je,mkdirSync as no,readdirSync as ro,readFileSync as oo,renameSync as Wt,statSync as Zt,unlinkSync as Yt,writeFileSync as so}from"node:fs";import{basename as io,dirname as Xt,join as qt,relative as ao}from"node:path";function g(e){process.stderr.write(`[ev-ai-agent-hook] ${e}
|
|
5
|
+
`)}function K(e,t){no(Xt(e),{recursive:!0});let n=qt(Xt(e),`.${io(e)}.${process.pid}.${to(4).toString("hex")}.tmp`);try{so(n,t,"utf8");try{Wt(n,e)}catch(r){let o=r instanceof Error&&"code"in r?r.code:void 0;if(o==="EEXIST"||o==="EPERM"||o==="EACCES"){Yt(e),Wt(n,e);return}throw r}}catch(r){try{Yt(n)}catch{}throw r}}function ye(){return new Date().toISOString().replace(/\.\d{3}Z$/,"Z")}function Qt(){process.stdout.write('{"continue":true}')}function y(e){let t=process.env[e];return t===void 0||t===""?void 0:t}async function Ve(){return new Promise(e=>{let t="";if(process.stdin.isTTY){e("");return}process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{t+=n}),process.stdin.on("end",()=>{e(t)}),process.stdin.on("error",()=>{e(t)}),process.stdin.resume()})}async function ze(e){return new Promise(t=>{let n="",r=!1,o=i=>{r||(r=!0,clearTimeout(s),t(i||"{}"))},s=setTimeout(()=>{o(n)},e);if(process.stdin.isTTY){o("{}");return}process.stdin.setEncoding("utf8"),process.stdin.on("data",i=>{n+=i}),process.stdin.on("end",()=>{o(n)}),process.stdin.on("error",()=>{o(n)}),process.stdin.resume()})}async function v(e,t,n=3e3,r={}){let{execFile:o}=await import("node:child_process"),{promisify:s}=await import("node:util"),i=s(o);try{let{stdout:a}=await i(e,t,{timeout:n,windowsHide:!0,maxBuffer:1048576,cwd:r.cwd});return{ok:!0,stdout:a.trim()}}catch(a){let c=a,l=typeof c.code=="number"?c.code:typeof c.status=="number"?c.status:void 0;return{ok:!1,code:l,spawnFailed:l===void 0}}}async function C(e,t,n=3e3,r={}){let o=await v(e,t,n,r);return o.ok?o.stdout:""}async function Je(e=process.cwd()){let t=await v("git",["rev-parse","--show-toplevel"],2e3,{cwd:e});if(t.ok&&t.stdout)return{root:t.stdout,inGitRepo:!0};if(y("EV_AI_HOOK_DEBUG")){let r=t.ok?"empty stdout":t.spawnFailed?"spawn failed":`exit ${String(t.code??"unknown")}`;g(`DEBUG: git rev-parse --show-toplevel failed (${r}) cwd=${e}`)}let n=y("CURSOR_PROJECT_DIR")??y("CLAUDE_PROJECT_DIR");if(n&&je(n)){let r=await v("git",["rev-parse","--show-toplevel"],2e3,{cwd:n});return r.ok&&r.stdout?{root:r.stdout,inGitRepo:!0}:{root:n,inGitRepo:!1}}return{root:e,inGitRepo:!1}}async function We(e=process.cwd()){return(await Je(e)).root}function w(e,t){try{return JSON.parse(e)}catch{return t}}var Ge=new Map;function q(e,t){let n=Ge.get(e);if(n!==void 0)return n;try{let r=w(oo(e,"utf8"),t);return Ge.set(e,r),r}catch{return Ge.set(e,t),t}}function z(e){return typeof e=="string"?e:""}function J(e,t){let n=e[t];if(typeof n=="string"||typeof n=="number"||typeof n=="boolean")return n;if(!t.includes("."))return;let r=t.split("."),o=e;for(let s of r){if(o===null||typeof o!="object"||Array.isArray(o))return;o=o[s]}if(typeof o=="string"||typeof o=="number"||typeof o=="boolean")return o}function f(e,t){let n=J(e,t);return typeof n=="string"?n:""}var M=500;function oe(e,t=2){if(!je(e))return{entries:[],truncated:!1};let n=[],r=!1,o=(s,i)=>{if(i>t||r)return;let a;try{a=ro(s,{withFileTypes:!0})}catch{return}for(let c of a){if(r)return;let l=qt(s,c.name);if(c.isDirectory()){o(l,i+1);continue}if(c.isFile()){try{n.push({name:ao(e,l),size:Zt(l).size})}catch{continue}if(n.length>=M){r=!0;return}}}};return o(e,1),{entries:n,truncated:r}}function se(e){return je(e)?{present:!0,size:Zt(e).size}:{present:!1,size:0}}function ie(e){if(e===void 0||e==="")return!1;let t=e.trim().toLowerCase();return t!=="0"&&t!=="false"&&t!=="no"}var fo=["CIRCLECI","BUILDKITE","TF_BUILD","JENKINS_URL","JENKINS_HOME","CODEBUILD_BUILD_ID","DRONE","DRONE_BUILD_NUMBER","TEAMCITY_VERSION","TRAVIS","APPVEYOR","BITBUCKET_BUILD_NUMBER"];function po(e){return fo.some(t=>!!I(t,e))}function mo(e){if(I("KUBERNETES_SERVICE_HOST",e)||ie(I("REMOTE_CONTAINERS",e))||ie(I("DEVCONTAINER",e)))return!0;try{if(co("/.dockerenv")||lo("/proc/1/environ","utf8").includes("container="))return!0}catch{}return!1}function tn(e){return["VSCODE_PID","VSCODE_IPC_HOOK","CURSOR_EXTENSION_HOST_ROLE","CURSOR_WORKSPACE_LABEL"].some(t=>!!I(t,e))}function go(e,t=process.platform){return tn(e)?t==="darwin"||t==="win32"?!0:["__CFBundleIdentifier","DISPLAY","WAYLAND_DISPLAY","SESSIONNAME"].some(n=>!!I(n,e)):!1}function _o(e){return e===void 0?!1:e.trim().toLowerCase().startsWith("bc-")}function ho(e){return e==="linux"}function I(e,t){if(t){let n=t[e];return n===void 0||n===""?void 0:n}return y(e)}function Eo(e,t,n){return e.trim().toLowerCase()==="cursor"&&t.trim().toLowerCase()==="ubuntu"&&!!So(I("CURSOR_VERSION",n))}function So(e){if(e===void 0)return null;let t=e.trim();return t.length>0?t:null}function Ye(e){if(_o(e.sessionId))return!0;let t=e.hostname??en(),n=e.osUser??nn(e.env);return Eo(t,n,e.env)}function Io(e){return ie(I("CURSOR_AGENT",e.env))?!0:Ye(e)}function Ro(e){return!!(process.stdin.isTTY||process.stdout.isTTY||(I("TERM",e)??I("TERM_PROGRAM",e))||(I("SSH_TTY",e)??I("SSH_CONNECTION",e))||(I("__CFBundleIdentifier",e)??I("XPC_SERVICE_NAME",e))||tn(e)||["DISPLAY","WAYLAND_DISPLAY","XDG_SESSION_TYPE","DBUS_SESSION_BUS_ADDRESS"].some(t=>!!I(t,e))||I("SESSIONNAME",e))}function ae(e={}){let t=e.env;if(I("GITHUB_ACTIONS",t))return"github_actions";if(ie(I("CLAUDE_CODE_REMOTE",t)))return"claude_remote";let n=e.platform??process.platform;if(!go(t,n)&&Io(e)&&(ie(I("CURSOR_AGENT",t))||ho(n)))return"cursor_cloud";if(I("CODESPACES",t)||I("CODESPACE_NAME",t))return"codespaces";if(I("GITLAB_CI",t))return"gitlab_ci";if(po(t))return"managed";let r=I("CI",t);return r&&r!=="false"&&r!=="0"?"managed":mo(t)?"container":Ro(t)?"interactive":"unknown"}async function Xe(){return await C("systemd-detect-virt",[],1e3)}function nn(e=process.env,t=uo){for(let n of["USER","LOGNAME","USERNAME"]){let r=e[n];if(typeof r=="string"){let o=r.trim();if(o.length>0)return o}}try{return t().username??""}catch{return""}}async function Ze(){let e=process.platform==="darwin"?"Darwin":process.platform==="win32"?"Windows_NT":"Linux",t="";if(process.platform==="darwin")t=await C("sw_vers",["-productVersion"],1e3);else if(process.platform==="linux"){try{let{readFileSync:s}=await import("node:fs"),i=s("/etc/os-release","utf8"),a=i.match(/^PRETTY_NAME="?([^"\n]+)"?/m)?.[1],c=i.match(/^VERSION_ID="?([^"\n]+)"?/m)?.[1];t=a??c??""}catch{t=await C("lsb_release",["-sd"],1e3).then(s=>s.replace(/^"|"$/g,""))}t||(t=await C("uname",["-r"],1e3))}else t=await C("ver",[],1e3);let n=nn(),r=(process.env.SHELL??"").split(/[/\\]/).pop()??"",o="";try{o=await C("tty",[],500),o.includes("not a tty")&&(o="")}catch{o=""}return{os:e,os_version:t||null,user:n||null,shell:r||null,tty:o||null}}function ce(){return en()}var Ao="installation.json",To="cloud-bootstrap.lock",Oo=6e4;function pn(e,t,n){let r=`${e}:${t??""}`;return n?`${n}:${r}`:r}function le(e=Qe()){return et(e,".ev-ai","agent-hook")}function ko(e=Qe()){return et(le(e),Ao)}function mn(e){return et(Ce(e),To)}function gn(){return yo(8).toString("hex")}function Q(e){return cn("sha256").update(e).digest("hex").slice(0,16)}function E(e){if(e===void 0)return null;let t=e.trim();return t.length>0?t:null}function _n(e){return/^[A-Za-z0-9._-]{8,64}$/.test(e)}function xo(e=process.env){let t=E(e.EV_AI_HOOK_INSTALLATION_ID);if(t){if(!_n(t)){g(`WARN: ignoring EV_AI_HOOK_INSTALLATION_ID (expected 8\u201364 chars [A-Za-z0-9._-], got length ${t.length})`);return}return t}}function hn(e,t){return e&&_n(e)?e:(e&&g(`WARN: ignoring installation id override (expected 8\u201364 chars [A-Za-z0-9._-], got length ${e.length})`),xo(t))}function No(e){return/^[0-9a-f]{16}$/.test(e)}function wo(e=process.env){if(E(e.GITHUB_ACTIONS)){let t=E(e.GITHUB_REPOSITORY_ID)??E(e.GITHUB_REPOSITORY),n=E(e.GITHUB_ACTOR)??E(e.GITHUB_TRIGGERING_ACTOR)??E(e.GITHUB_USER);if(t&&n)return Q(`github_actions|${t}|${n}`)}if(E(e.CODESPACES)||E(e.CODESPACE_NAME)){let t=E(e.CODESPACE_NAME);if(t)return Q(`codespaces|${t}`);let n=E(e.GITHUB_REPOSITORY_ID)??E(e.GITHUB_REPOSITORY),r=E(e.GITHUB_USER)??E(e.GITHUB_ACTOR);if(n&&r)return Q(`codespaces|${n}|${r}`)}if(E(e.GITLAB_CI)){let t=E(e.CI_PROJECT_ID)??E(e.CI_PROJECT_PATH),n=E(e.GITLAB_USER_LOGIN)??E(e.GITLAB_USER_EMAIL)??E(e.GITLAB_USER_NAME);if(t&&n)return Q(`gitlab|${t}|${n}`)}return null}var bo="cursoragent@cursor.com";function Uo(e){let t=E(e.CURSOR_USER_EMAIL);return!t||t.toLowerCase()===bo?null:t}function vo(e,t){return E(e.CURSOR_PROJECT_DIR)??E(e.CLAUDE_PROJECT_DIR)??t}function Po(e){return e.replace(/^([a-z]+:\/\/)[^/@]+@/i,"$1").replace(/\.git$/i,"").toLowerCase()}async function Lo(e){let t=await C("git",["config","--get","remote.origin.url"],2e3,{cwd:e});return t?Po(t):e}async function Mo(e){let t=E(await C("git",["config","--local","--get","user.email"],2e3,{cwd:e})||void 0);if(t&&!V(null,t))return t;let n=E(await C("git",["log","-1","--format=%ae"],2e3,{cwd:e})||void 0);return n&&!V(null,n)?n:null}function Do(e,t){let n=vo(e,t);return n?Q(`cursor_cloud|${n}|${Uo(e)??""}`):null}async function Ho(e,t){let n=E(e.CLAUDE_PROJECT_DIR)??t;if(!n)return null;let r=await Lo(n),o=await Mo(n);return Q(`claude_remote|${r}|${o??""}`)}function rn(e,t){let n=hn(e,t);if(n)return n;let r=wo(t);return r||gn()}async function Fo(e){let n=await C("git",["config","--get","remote.origin.url"],2e3,{cwd:e})||Co(e);return cn("sha256").update(n).digest("hex").slice(0,16)}function Bo(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t={};for(let[n,r]of Object.entries(e))typeof r=="string"&&r.length>0&&(t[n]=r);return Object.keys(t).length>0?t:void 0}function $o(e){try{let t=JSON.parse(e);if(typeof t.installation_id!="string"||t.installation_id.length===0)return;let n=Bo(t.platform_agent_ids);return{installation_id:t.installation_id,...t.pinned===!0?{pinned:!0}:{},...n?{platform_agent_ids:n}:{},...typeof t.operator_identity_hash=="string"?{operator_identity_hash:t.operator_identity_hash}:{},...typeof t.operator_identity_sent_at=="string"?{operator_identity_sent_at:t.operator_identity_sent_at}:{}}}catch{return}}function W(e){if(ln(e))try{return $o(un(e,"utf8"))}catch{}}function tt(e){return W(e)}function En(e,t,n){let r=W(e);if(!r||r.operator_identity_hash===t&&r.operator_identity_sent_at===n)return;let o={...r,operator_identity_hash:t,operator_identity_sent_at:n};try{K(e,`${JSON.stringify(o,null,2)}
|
|
6
|
+
`)}catch(s){let i=s instanceof Error?s.message:String(s);g(`WARN: operator identity cache write failed open: ${i}`)}}function Sn(e,t=Date.now()){if(!e)return!0;if(W(e)?.operator_identity_hash)return!1;let n=mn(e);try{if(ln(n)){let r=Number.NaN;try{r=Number(un(n,"utf8").trim())}catch{}let o=t-r;if(Number.isFinite(o)&&o>=0&&o<Oo)return!1;try{dn(n)}catch{}}}catch{}try{return qe(Ce(n),{recursive:!0}),fn(n,`${t}
|
|
7
|
+
`,{encoding:"utf8",flag:"wx"}),!0}catch(r){if(Cn(r))return!1;let o=r instanceof Error?r.message:String(r);return g(`WARN: cloud bootstrap claim failed open: ${o}`),!0}}function In(e){if(e)try{dn(mn(e))}catch{}}function Rn(e,t){let r=W(e)?.platform_agent_ids?.[t];return typeof r=="string"&&r.length>0?r:void 0}function yn(e,t,n){if(!n)return;let r=W(e);if(!r||r.platform_agent_ids?.[t]===n)return;let o={installation_id:r.installation_id,platform_agent_ids:{...r.platform_agent_ids,[t]:n},...r.operator_identity_hash?{operator_identity_hash:r.operator_identity_hash}:{},...r.operator_identity_sent_at?{operator_identity_sent_at:r.operator_identity_sent_at}:{}};try{K(e,`${JSON.stringify(o,null,2)}
|
|
8
|
+
`)}catch(s){let i=s instanceof Error?s.message:String(s);g(`WARN: platform_agent_id cache write failed open: ${i}`)}}function Cn(e){return e instanceof Error&&"code"in e&&e.code==="EEXIST"}function Ko(e,t){qe(Ce(e),{recursive:!0}),fn(e,`${JSON.stringify(t,null,2)}
|
|
9
|
+
`,{encoding:"utf8",flag:"wx"})}function on(e,t){try{return Ko(e,t),t}catch(n){if(!Cn(n))throw n;return W(e)}}function sn(e,t){qe(Ce(e),{recursive:!0}),K(e,`${JSON.stringify(t,null,2)}
|
|
10
|
+
`)}function an(e,t){return{installation_id:e,...t&&t===e?{pinned:!0}:{}}}async function An(e,t={}){let n=t.home??Qe(),r=t.env??process.env,o=await Fo(e),s=ko(n),i={sessionId:t.sessionId,hostname:E(r.HOSTNAME)??void 0,osUser:E(r.USER)??E(r.LOGNAME)??E(r.USERNAME)??void 0,env:r},a=ae(i),c=hn(t.overrideId,r),l=a==="cursor_cloud"&&Ye(i)?Do(r,e):a==="claude_remote"?await Ho(r,e):null,u=W(s);if(u){let S=u;if(c&&c===u.installation_id&&u.pinned!==!0&&(S={...u,pinned:!0},sn(s,S)),!!l&&l!==S.installation_id&&!c&&S.pinned!==!0&&No(S.installation_id)&&l){let T={installation_id:l,...S.platform_agent_ids?{platform_agent_ids:S.platform_agent_ids}:{}};return sn(s,T),{installationId:l,storePath:s,repoKey:o}}return{installationId:S.installation_id,storePath:s,repoKey:o}}let d=c??l??rn(void 0,r),m=on(s,an(d,c));if(m)return{installationId:m.installation_id,storePath:s,repoKey:o};let p=c??l??rn(void 0,r),_=on(s,an(p===d?gn():p,c));if(_)return{installationId:_.installation_id,storePath:s,repoKey:o};throw new Error(`Failed to create installation record at ${s}`)}var Go=new Set(["localhost","127.0.0.1","[::1]","::1"]),Tn=/^[A-Za-z0-9._~-]+$/;function On(e){for(let t=0;t<e.length;t++){let n=e.charCodeAt(t);if(n<=32||n===127||n===39)return!0}return!1}function Ae(e){try{let t=new URL(e);return t.protocol==="https:"?!0:t.protocol==="http:"?Go.has(t.hostname):!1}catch{return!1}}function kn(e){let t;try{t=new URL(e)}catch{return`invalid URL (got: ${e})`}if(!Ae(e))return`must be https (or http on localhost / 127.0.0.1 / ::1) (got: ${e})`;let n=jo(e);if(!n)return`must end with /{orgToken}/hook (got: ${e})`;if(!Tn.test(n))return`org token must match ${Tn.source} (got: ${n})`;if(On(e))return`must not contain whitespace, control characters, or single quotes (got: ${e})`;if(On(t.pathname))return`pathname must not contain whitespace, control characters, or single quotes (got: ${e})`}function xn(e){return new URL(e).toString()}function jo(e){try{let n=new URL(e).pathname.split("/").filter(r=>r.length>0);if(n.length>=2&&n[n.length-1]==="hook"){let r=n[n.length-2];return r.length>0?r:void 0}return}catch{return}}function nt(e){try{let t=new URL(e),n=t.pathname.split("/").filter(r=>r.length>0);return n.length>=2&&n[n.length-1]==="hook"&&(n[n.length-2]="***",t.pathname=`/${n.join("/")}`),t.toString()}catch{return"<invalid-url>"}}function Nn(e){if(e.collector_url)return e.collector_url;let t=e.repo_ingest_token?.trim();return t?Ie(t):""}var wn=/(?:^|\/|[\s"'=(])(?:\.cursor\/|\.claude\/|\.agents\/)skills(?:-cursor)?\/([^/]+)\/SKILL\.md/i,bn=/(?:^|\/|[\s"'=(])\.codex\/commands\/([^/]+)\.md\b/i,Vo=/(?:^|\s)\/([a-z][a-z0-9-]{1,63})\b/gi,zo=new Set(["applications","app","bin","boot","data","dev","etc","home","lib","media","mnt","node_modules","opt","pkg","private","proc","projects","repos","run","sbin","src","srv","sys","tmp","usr","users","var","volumes","workspace","workspaces"]),Jo=new Set(["read","read_file","view"]),Wo=new Set(["bash","shell","zsh"]);function Yo(e){let t=e.replace(/\\/g,"/");return wn.exec(t)?.[1]??null}function Xo(e){let t=e.replace(/\\/g,"/"),r=bn.exec(t)?.[1];return r?r.toLowerCase():null}function rt(e){return Yo(e)??Xo(e)}function Zo(e){for(let t of["path","file_path","target_file"]){let n=e[t];if(typeof n=="string"&&n.length>0)return n}return null}function Te(e){if(typeof e=="string")try{let t=JSON.parse(e);return Te(t)}catch{return null}return!e||typeof e!="object"?null:Zo(e)}function qo(e){if(!e||typeof e!="object")return null;let t=e.command;return typeof t=="string"&&t.length>0?t:null}function Qo(e){let t=e.replace(/\\/g,"/"),n=wn.exec(t);if(n?.[1])return n[1];let o=bn.exec(t)?.[1];return o?o.toLowerCase():null}function es(e){return typeof e.tool_name=="string"?e.tool_name:typeof e.tool=="string"?e.tool:""}function Un(e){let t=es(e).toLowerCase();if(Jo.has(t)){let n=Te(e.tool_input)??z(e.file_path),r=n?rt(n):null;if(r)return r}if(Wo.has(t)){let n=qo(e.tool_input)??z(e.command);return n?Qo(n):null}return null}function ts(e){let t=new Set,n=[];for(let r of e.matchAll(Vo)){let o=r[1]?.toLowerCase();!o||t.has(o)||zo.has(o)||(t.add(o),n.push(o))}return n}function ns(e){return z(e.prompt)}function vn(e){let t=f(e,"command_name");if(t){let r=f(e,"expansion_type");if(r&&r!=="slash_command")return[];let o=t.replace(/^\//,"").toLowerCase();return o?[o]:[]}let n=ns(e);return n?ts(n):[]}function ot(e){return e!==void 0&&Jt.includes(e)}function Oe(e,t){let n=e[t+1];return n&&!n.startsWith("--")?{value:n,next:t+1}:{next:t}}function ke(e){let t,n,r,o,s;for(let i=0;i<e.length;i++){let a=e[i];if(a!==void 0){if(a==="--runner"){let c=Oe(e,i);t=c.value,i=c.next;continue}if(a.startsWith("--runner=")){t=a.slice(9);continue}if(a==="--url"){let c=Oe(e,i);c.value&&(r=c.value),i=c.next;continue}if(a.startsWith("--url=")){r=a.slice(6);continue}if(a==="--token"){let c=Oe(e,i);c.value&&(o=c.value),i=c.next;continue}if(a.startsWith("--token=")){o=a.slice(8);continue}if(a==="--base-url"){let c=Oe(e,i);c.value&&(s=c.value),i=c.next;continue}if(a.startsWith("--base-url=")){s=a.slice(11);continue}!a.startsWith("-")&&n===void 0&&(n=a)}}return{runner:ot(t)?t:void 0,event:n,collectorUrl:r,orgToken:o,baseUrl:s}}function st(e){let t=e.collectorUrl?.trim(),n;if(t)n=t;else{let o=e.orgToken?.trim();o&&(n=Ie(o,e.baseUrl?.trim()??void 0))}if(!n)return;let r=kn(n);if(r){g(`WARN: ignoring --url/--token collector override: ${r}`);return}return xn(n)}function Pn(e,t){if(f(e,"conversation_id"))return!0;if(t==="")return!1;let n=t[0];return n?.toLowerCase()===n}function rs(){return!!(y("CURSOR_VERSION")??y("CURSOR_PROJECT_DIR"))}function it(e,t,n){return e!=="claude"&&e!=="codex"?!1:Pn(t,n)?!0:rs()}function ue(e,t,n,r){if(Pn(e,t))return"cursor";if(ot(r))return r;let o=f(e,"conversation_id"),s=f(e,"turn_id"),i=f(e,"session_id"),a=t.toLowerCase(),c="unknown";return o||t===a&&t!==""?c="cursor":s?c="codex":(i||a==="sessionstart"||a==="sessionend"||a==="stop"||a==="stopfailure"||a==="pretooluse"||a==="posttooluse"||a==="posttoolusefailure"||a==="permissiondenied"||a==="subagentstart"||a==="subagentstop"||a==="userpromptexpansion")&&(c="claude"),ot(n)&&(c=n),c}function xe(e,t){let n=e.toLowerCase();return n==="sessionend"||n==="stopfailure"||n==="subagentstop"?!0:n==="stop"&&t==="codex"}function os(e){switch(e){case"sessionstart":return"session_start";case"stop":case"sessionend":case"stopfailure":return"session_end";case"pretooluse":case"posttooluse":case"posttoolusefailure":case"permissiondenied":case"beforemcpexecution":case"beforeshellexecution":case"aftershellexecution":case"beforereadfile":case"afterfileedit":case"subagentstart":case"subagentstop":return"tool_invoked";case"beforesubmitprompt":case"userpromptexpansion":case"userpromptsubmit":return"skill_invoked";default:return""}}function Ln(e){let t=e.toLowerCase();return t==="posttooluse"?!0:t==="posttoolusefailure"||t==="permissiondenied"?!1:null}function Mn(e,t,n){let r=f(e,"session_id")||f(e,"conversation_id"),o=f(e,"prompt.id")||f(e,"prompt_id")||f(e,"generation_id")||f(e,"turn_id"),s=f(e,"hook_event_name")||f(e,"event"),i=f(e,"source"),a=ue(e,s,t,n);return{sessionId:r,turnId:o,runnerEvent:s,hookSource:i,runnerPlatform:a}}var ss=["session_start","session_end","tool_invoked","skill_invoked"];function is(e){return ss.includes(e)}function Dn(e,t){return e&&is(e)?e:os(t.toLowerCase())}var as={beforeshellexecution:"Shell",aftershellexecution:"Shell",beforereadfile:"Read",afterfileedit:"Write"};function cs(e){return/^mcp__/i.test(e)||/^MCP:/i.test(e)}function Hn(e,t=""){let n=f(e,"tool_name")||f(e,"tool")||null,r=t.toLowerCase();n?r==="beforemcpexecution"&&!cs(n)&&(n=`MCP:${n}`):n=as[r]??null;let o=e.tool_input,i=(o&&typeof o=="object"?z(o.skill)||z(o.skill_name):"")||f(e,"skill_name")||null,a=n&&e.tool_name!==n&&e.tool!==n?{...e,tool_name:n}:e;return i??=Un(a),{toolName:n,skillName:i}}var ls=/^[A-Za-z][A-Za-z0-9_.:-]{0,63}$/;function Fn(e){for(let t of["subagent_type","agent_type"]){let n=f(e,t);if(n&&ls.test(n))return n}return null}function Bn(e){let t=J(e,"duration_ms");if(typeof t=="number")return t;let n=J(e,"duration");return typeof n=="number"?n:null}var us="error",ds="interrupted",fs="permission_denied",ps=/^[A-Za-z][A-Za-z0-9_.-]{0,63}$/;function at(e){return ps.test(e)?e:null}function ms(e){for(let t of["failure_type","error_type"]){let n=at(f(e,t));if(n)return n}return null}function $n(e,t){return J(e,"is_interrupt")===!0?ds:t.toLowerCase()==="permissiondenied"?fs:ms(e)??us}function gs(e,t){let n=null;for(let r of t)r&&(e===r||e.startsWith(`${r}_`)||e.startsWith(`${r}-`))&&(n===null||r.length>n.length)&&(n=r);return n}function Kn(e,t=[]){if(!e)return{mcpServer:null,mcpTool:null};let n=/^mcp__(.+?)__(.+)$/i.exec(e);if(n?.[1]&&n[2])return{mcpServer:n[1],mcpTool:n[2]};if(/^MCP:/i.test(e)){let r=e.slice(4);if(!r)return{mcpServer:null,mcpTool:null};let o=r.indexOf(":");return o>0?{mcpServer:r.slice(0,o),mcpTool:r.slice(o+1)||null}:{mcpServer:gs(r,t),mcpTool:r}}return{mcpServer:null,mcpTool:null}}var zn=3e4,Rs="claims",ys=!0,Cs=100,As=new Set(["sessionstart","sessionend","stopfailure"]),Ts=["tool_name","tool","command","file_path","url"];function Os(e=Vn()){return ct(le(e),Rs)}function Jn(e){let t=e.split(`
|
|
11
|
+
`,1)[0]??"";return Number(t.trim())}function Wn(e){return _s("sha256").update(e).digest("hex").slice(0,32)}function ks(e){let t=[];for(let n of Ts){let r=f(e,n).trim();r&&t.push(`${n}=${r}`)}return t.length===0?"":Wn(t.join("\0"))}function xs(e){let t=e.sessionId.trim();if(!t)return;let n=e.runnerEvent.trim().toLowerCase(),r=e.turnId.trim(),o=e.toolUseId.trim(),s=e.subagentId?.trim()??"",i=e.callFingerprint?.trim()??"",a=!!(o||r||s),c=As.has(n);if(!a&&!c)return;let l=e.runnerPlatform.trim()||"unknown";return Wn(`${l}|${t}|${n}|${r}|${o}|${i}|${s}`)}function Ns(e){return e instanceof Error&&"code"in e&&e.code==="EEXIST"}function ws(e,t){return ct(e,t)}function bs(e,t=Date.now()){let n;try{n=Ss(e)}catch{return}let r=0;for(let o of n){if(r>=Cs)break;r+=1;let s=ct(e,o),i=Number.NaN;try{i=Jn(Gn(s,"utf8"))}catch{continue}let a=t-i;if(!(!Number.isFinite(a)||a<0||a<zn))try{jn(s)}catch{}}}function Us(e,t,n=Date.now()){let r=ws(t,e);try{if(hs(r)){let o=Number.NaN;try{o=Jn(Gn(r,"utf8"))}catch{}let s=n-o;if(Number.isFinite(s)&&s>=0&&s<zn)return!1;try{jn(r)}catch{}}}catch{}try{Es(t,{recursive:!0}),Is(r,`${n}
|
|
12
|
+
`,{encoding:"utf8",flag:"wx"})}catch(o){if(Ns(o))return!1;let s=o instanceof Error?o.message:String(o);return g(`WARN: event claim failed open: ${s}`),!0}return bs(t,n),!0}function vs(e,t,n){let r=f(e,"session_id")||f(e,"conversation_id"),o=f(e,"prompt.id")||f(e,"prompt_id")||f(e,"generation_id")||f(e,"turn_id"),s=f(e,"tool_use_id"),i=f(e,"subagent_id")||f(e,"agent_id"),a=ue(e,t,void 0,n),c=ks(e);return{runnerPlatform:a,sessionId:r,runnerEvent:t,turnId:o,toolUseId:s,subagentId:i,callFingerprint:c}}function Yn(e,t,n,r=Vn(),o=Date.now()){if(!ys)return!0;let s=xs(vs(e,t,n));if(!s)return!0;let i=Us(s,Os(r),o);return!i&&y("EV_AI_HOOK_DEBUG")&&g(`DEBUG: duplicate hook event suppressed (claim ${s.slice(0,8)}\u2026)`),i}var lt={claude:".claude",cursor:".cursor",codex:".codex",opencode:".opencode"};function de(e){let n=e.replace(/^\/+|\/+$/g,"").toLowerCase().split("/").filter(Boolean);return n.length<2?"":n.join("/")}function Ps(e){if(!e)return"";let t=e.replace(/^([a-z]+:\/\/)[^/@]+@/i,"$1");t=t.replace(/\.git$/i,"");let n=t.match(/^git@[^:]+:(.+)$/);if(n?.[1])return de(n[1]);let r=t.match(/^ssh:\/\/[^/]+\/(.+)$/i);if(r?.[1])return de(r[1]);t=t.replace(/^https:\/\//i,""),t=t.replace(/^http:\/\//i,""),t=t.replace(/^ssh:\/\//i,"");let o=t.match(/^[^/]+\/(.+)$/);return o?.[1]?de(o[1]):de(t)}async function fe(e=process.cwd()){let t=await v("git",["rev-parse","--is-inside-work-tree"],2e3,{cwd:e});if(!t.ok||t.stdout!=="true")return null;let[n,r,o,s]=await Promise.all([v("git",["remote","get-url","origin"],2e3,{cwd:e}),v("git",["branch","--show-current"],2e3,{cwd:e}),v("git",["rev-parse","HEAD"],2e3,{cwd:e}),v("git",["status","--porcelain"],2e3,{cwd:e})]),i=n.ok?n.stdout:null;return{remote:i===null?null:i.replace(/^([a-z]+:\/\/)[^/@]+@/i,"$1"),branch:r.ok?r.stdout:null,head:o.ok?o.stdout:null,dirty:s.ok?s.stdout.length>0:null}}async function Xn(e,t,n,r=process.cwd(),o,s,i){if(t)return t;let a=lt[n];if(!a)return"";let c=pn(n,e.scope_path,i);if(s){let _=Rn(s,c);if(_)return _}let l=o??await fe(r),u=l?.remote?Ps(l.remote):"";if(u||(u=de(process.env.GITHUB_REPOSITORY??"")),!u)return"";let d=e.scope_path??"",m=d?`${d}/`:"",p=`${u}:${m}${a}`;return s&&yn(s,c,p),p}var G=Xr(Qn(),1);import{existsSync as js,readFileSync as Vs}from"node:fs";import{homedir as er}from"node:os";import{join as zs}from"node:path";var Js="cloud-cache.json",Ws=1440*60*1e3,Ys=900*1e3;function Xs(e=er()){return zs(le(e),Js)}function Zs(e){if(!js(e))return;let t=w(Vs(e,"utf8"),{});if(!(typeof t.context!="string"||typeof t.probed_at!="number"||t.result!==null&&t.result!==void 0&&typeof t.result!="object"))return{context:t.context,probed_at:t.probed_at,result:t.result??null}}function qs(e,t){try{K(e,`${JSON.stringify(t)}
|
|
13
|
+
`)}catch(n){let r=n instanceof Error?n.message:String(n);g(`WARN: cloud cache write failed open: ${r}`)}}function Qs(e,t,n){if(!e||e.context!==t)return!1;let r=e.result===null?Ys:Ws;return n-e.probed_at<r}async function ei(e){let t=await fetch("http://169.254.169.254/latest/api/token",{method:"PUT",headers:{"X-aws-ec2-metadata-token-ttl-seconds":"60"},signal:AbortSignal.timeout(e)}).catch(()=>{});if(!t?.ok)return;let n=(await t.text()).trim();if(!n)return;let r={"X-aws-ec2-metadata-token":n},[o,s]=await Promise.all([fetch("http://169.254.169.254/latest/meta-data/placement/region",{headers:r,signal:AbortSignal.timeout(e)}).catch(()=>{}),fetch("http://169.254.169.254/latest/meta-data/instance-id",{headers:r,signal:AbortSignal.timeout(e)}).catch(()=>{})]);if(!o?.ok&&!s?.ok)return;let i=o?.ok?(await o.text()).trim():"",a=s?.ok?(await s.text()).trim():"";if(!(!i&&!a))return{provider:"aws",region:i,instance_id:a}}async function ti(e){let t=await fetch("http://metadata.google.internal/computeMetadata/v1/instance/?recursive=true",{headers:{"Metadata-Flavor":"Google"},signal:AbortSignal.timeout(e)}).catch(()=>{});if(!t?.ok)return;let n=await t.json(),r=typeof n.zone=="string"?n.zone.split("/").pop()??"":"",o=n.id===void 0?"":String(n.id);if(!(!r&&!o))return{provider:"gcp",region:r,instance_id:o}}async function ni(e){let t=await fetch("http://169.254.169.254/metadata/instance?api-version=2021-02-01",{headers:{Metadata:"true"},signal:AbortSignal.timeout(e)}).catch(()=>{});if(!t?.ok)return;let n=await t.json(),r=n.compute?.location??"",o=n.compute?.vmId??"";if(!(!r&&!o))return{provider:"azure",region:r,instance_id:o}}async function ri(e){let t=await Promise.allSettled([ei(e),ti(e),ni(e)]);for(let n of t)if(n.status==="fulfilled"&&n.value)return n.value;return null}async function ut(e,t){if(e==="interactive")return null;let n=t?.home??er(),r=t?.timeoutMs??1e3,o=t?.nowMs??Date.now(),s=Xs(n),i=Zs(s);if(Qs(i,e,o))return i.result;let a=await ri(r);return qs(s,{context:e,probed_at:o,result:a}),a}import{existsSync as oi}from"node:fs";import{homedir as si}from"node:os";import{join as dt}from"node:path";function ft(e,t,n){if(!oi(e))return;let r=q(e,{});for(let o of Object.keys(r.mcpServers??{}))n.set(o,{name:o,source:t})}async function pt(e,t=process.cwd(),n="claude",r=si()){let o=new Map;for(let s of e.mcp_servers??[])s.name&&o.set(s.name,{name:s.name,source:"manifest"});return n==="claude"&&ft(dt(r,".claude.json"),"claude_json_user",o),ft(dt(t,".mcp.json"),"mcp_json",o),ft(dt(t,".cursor/mcp.json"),"cursor_mcp",o),[...o.values()]}var ii=["CI","GITHUB_ACTIONS","GITLAB_CI","CIRCLECI","BUILDKITE","TF_BUILD","JENKINS_URL","JENKINS_HOME","CODEBUILD_BUILD_ID","DRONE","DRONE_BUILD_NUMBER","TEAMCITY_VERSION","TRAVIS","APPVEYOR","BITBUCKET_BUILD_NUMBER","KUBERNETES_SERVICE_HOST","REMOTE_CONTAINERS","DEVCONTAINER","GITHUB_REPOSITORY","GITHUB_REPOSITORY_ID","GITHUB_REF","GITHUB_SHA","GITHUB_RUN_ID","GITHUB_WORKFLOW","GITHUB_ACTOR","GITHUB_TRIGGERING_ACTOR","GITHUB_ACTOR_ID","GITHUB_USER","GITLAB_USER_LOGIN","GITLAB_USER_NAME","GITLAB_USER_EMAIL","BUILD_REQUESTEDFOR","BUILD_REQUESTEDFOREMAIL","BUILD_REQUESTEDFORID","BUILDKITE_BUILD_CREATOR","BUILDKITE_BUILD_CREATOR_EMAIL","BUILD_USER","BUILD_USER_ID","BUILD_USER_EMAIL","CHANGE_AUTHOR","CHANGE_AUTHOR_EMAIL","CIRCLE_USERNAME","CODEBUILD_INITIATOR","DRONE_COMMIT_AUTHOR","DRONE_COMMIT_AUTHOR_NAME","DRONE_COMMIT_AUTHOR_EMAIL","EV_AI_HOOK_OPERATOR_NAME","EV_AI_HOOK_OPERATOR_EMAIL","EV_AI_HOOK_OPERATOR_LOGIN","GIT_AUTHOR_NAME","GIT_AUTHOR_EMAIL","GIT_COMMITTER_NAME","GIT_COMMITTER_EMAIL","EMAIL","RUNNER_OS","RUNNER_ARCH","NODE_ENV","TERM_PROGRAM","CLAUDE_CODE_REMOTE","CLAUDE_CODE_REMOTE_SESSION_ID","CURSOR_AGENT","CURSOR_VERSION","CURSOR_CODE_REMOTE","CURSOR_USER_EMAIL","CODESPACES","CODESPACE_NAME","ANTHROPIC_BASE_URL","OPENAI_BASE_URL","OPENAI_API_BASE","AZURE_OPENAI_ENDPOINT","GOOGLE_GEMINI_BASE_URL","GEMINI_API_BASE","CLAUDE_CODE_USE_BEDROCK","CLAUDE_CODE_USE_VERTEX"],ai=["CURSOR_PROJECT_DIR"],ci=new Set(["key","api-key","api_key","apikey","token","sig","signature","access_token","password","pwd","secret","client_secret"]);function li(e){try{let t=new URL(e);(t.username||t.password)&&(t.username="",t.password="");for(let[n]of t.searchParams)ci.has(n.toLowerCase())&&t.searchParams.set(n,"[redacted]");return t.toString()}catch{return e}}function mt(e=process.env){let t=ii.map(r=>Object.prototype.hasOwnProperty.call(e,r)?{name:r,present:!0,value:li(e[r]??"")}:{name:r,present:!1}),n=ai.map(r=>({name:r,present:Object.prototype.hasOwnProperty.call(e,r)&&!!e[r]}));return[...t,...n]}import{createHash as ui}from"node:crypto";function A(e){return ui("sha256").update(e).digest("hex").slice(0,16)}function F(e,t){return`${e}\0${t}`}function tr(e){let t=e.indexOf("\0");return t<=0?null:{path:e.slice(0,t),name:e.slice(t+1)}}function gt(e){let n=[...e].sort((r,o)=>{let s=r.path.localeCompare(o.path);return s!==0?s:r.name.localeCompare(o.name)}).map(r=>`${r.path}|${r.name}|${r.content_hash}`).join(`
|
|
14
|
+
`);return A(n)}function di(e,t,n="git_config",r=null){return A(`${e??""}|${t??""}|${r??""}|${n}`)}function fi(e){let t=null,n=null;for(let r of e.split(`
|
|
15
|
+
`)){let o=r.trim();if(!o)continue;let s=o.indexOf(" ");if(s<=0)continue;let i=o.slice(0,s).toLowerCase(),a=o.slice(s+1).trim();a&&(i==="user.name"?t=a:i==="user.email"&&(n=a))}return{git_user_name:t,git_user_email:n,platform_login:null}}async function pi(e,t=C){let n=await t("git",["config","--get-regexp","^user\\.(name|email)$"],2e3,{cwd:e});return fi(n)}function mi(e=process.env){let t=h(e.GIT_AUTHOR_NAME),n=h(e.GIT_AUTHOR_EMAIL);if(t||n)return{git_user_name:t,git_user_email:n,platform_login:null,identity_source:"git_env"};let r=h(e.GIT_COMMITTER_NAME),o=h(e.GIT_COMMITTER_EMAIL);if(r||o)return{git_user_name:r,git_user_email:o,platform_login:null,identity_source:"git_env"};let s=h(e.EMAIL);return s?{git_user_name:null,git_user_email:s,platform_login:null,identity_source:"git_env"}:null}async function gi(e,t=C){let n=await t("git",["log","-1","--format=%an%x00%ae"],2e3,{cwd:e});if(!n)return null;let r=n.indexOf("\0"),o=(r>=0?n.slice(0,r):n).trim(),s=(r>=0?n.slice(r+1):"").trim();return!o&&!s?null:{git_user_name:o||null,git_user_email:s||null,platform_login:null,identity_source:"git_log"}}function B(e,t,n,r=null){return!e&&!t&&!r?null:{git_user_name:e,git_user_email:t,platform_login:r,identity_source:n}}function _i(e=process.env){let t=B(h(e.EV_AI_HOOK_OPERATOR_NAME),h(e.EV_AI_HOOK_OPERATOR_EMAIL),"configured",h(e.EV_AI_HOOK_OPERATOR_LOGIN));if(t)return t;let n=h(e.GITHUB_ACTOR)??h(e.GITHUB_TRIGGERING_ACTOR)??h(e.GITHUB_USER),r=B(n,null,"github",n);if(r)return r;let o=h(e.GITLAB_USER_LOGIN),s=B(h(e.GITLAB_USER_NAME)??o,h(e.GITLAB_USER_EMAIL),"gitlab",o);if(s)return s;let i=B(h(e.BUILD_REQUESTEDFOR),h(e.BUILD_REQUESTEDFOREMAIL),"azure_devops",h(e.BUILD_REQUESTEDFORID));if(i)return i;let a=h(e.BUILDKITE_BUILD_CREATOR_EMAIL),c=B(h(e.BUILDKITE_BUILD_CREATOR),a,"buildkite",a);if(c)return c;let l=B(h(e.BUILD_USER)??h(e.CHANGE_AUTHOR),h(e.BUILD_USER_EMAIL)??h(e.CHANGE_AUTHOR_EMAIL),"jenkins",h(e.BUILD_USER_ID));if(l)return l;let u=h(e.CIRCLE_USERNAME),d=B(u,null,"circleci",u);if(d)return d;let m=h(e.CODEBUILD_INITIATOR),p=B(m,null,"codebuild",m);if(p)return p;let _=B(h(e.DRONE_COMMIT_AUTHOR)??h(e.DRONE_COMMIT_AUTHOR_NAME),h(e.DRONE_COMMIT_AUTHOR_EMAIL),"drone",h(e.DRONE_COMMIT_AUTHOR));if(_)return _;if(nr(e.CLAUDE_CODE_REMOTE)||nr(e.CURSOR_AGENT)){let S=h(e.CURSOR_USER_EMAIL);return{git_user_name:null,git_user_email:S&&!V(null,S)?S:null,platform_login:null,identity_source:"cloud"}}return null}function _t(e){return!!((e.git_user_name??e.git_user_email)&&!V(e.git_user_name,e.git_user_email))}function h(e){if(e===void 0)return null;let t=e.trim();return t.length>0?t:null}function nr(e){if(e===void 0||e==="")return!1;let t=e.trim().toLowerCase();return t!=="0"&&t!=="false"&&t!=="no"}async function hi(e,t=C,n=process.env){let r=await pi(e,t);if(_t(r))return{...r,identity_source:"git_config"};let o=mi(n);if(o&&_t(o))return o;let s=_i(n);if(s&&(s.git_user_name||s.git_user_email||s.platform_login))return s;let i=await gi(e,t);return i&&_t(i)?i:s||(r.git_user_name||r.git_user_email?{...r,identity_source:"git_config"}:o||i||{git_user_name:null,git_user_email:null,platform_login:null,identity_source:"git_config"})}async function we(e){let{gitRoot:t,installationStorePath:n,forceResend:r}=e,o=e.exec??C,s=e.env??process.env,i=await hi(t,o,s),a=di(i.git_user_name,i.git_user_email,i.identity_source,i.platform_login),l=(n?tt(n):void 0)?.operator_identity_hash;if(!(r||l!==void 0&&l!==a||!l))return{commit:()=>{}};let p=n;return{operator:i,commit:()=>{p&&En(p,a,ye())}}}function ht(e){return e?!tt(e)?.operator_identity_hash:!0}function rr(e){return!0}import{existsSync as Bi,readFileSync as $i}from"node:fs";import{homedir as yr}from"node:os";import{join as P}from"node:path";import{basename as Hi,join as ee,resolve as gr}from"node:path";import{existsSync as or,readdirSync as Ei}from"node:fs";import{basename as Si,dirname as Ii,relative as Ri}from"node:path";var pe=class{constructor(t,n=""){this.home=t;this.pathPrefix=n}components=[];truncated=!1;pluginExpandRemaining;homeRel(t){let n=Ri(this.home,t).replace(/\\/g,"/"),r=!n||n.startsWith("..")?`external/${A(Ii(t))}/${Si(t)}`:n;return this.pathPrefix?`${this.pathPrefix}${r}`:r}get atGlobalCap(){return this.truncated||this.components.length>=M}get pluginBudgetSpent(){return this.pluginExpandRemaining!==void 0&&this.pluginExpandRemaining<=0}readEntries(t){if(!or(t))return[];try{return Ei(t,{withFileTypes:!0})}catch{return[]}}readJson(t,n){if(or(t))return q(t,n)}push(t){return this.components.length>=M?(this.truncated=!0,!1):this.pluginExpandRemaining!==void 0&&this.pluginExpandRemaining<=0?!1:(this.pluginExpandRemaining!==void 0&&(this.pluginExpandRemaining-=1),this.components.push(t),!0)}withPluginExpandCap(t,n){let r=this.pluginExpandRemaining;this.pluginExpandRemaining=t;try{let o=n(),s=t-(this.pluginExpandRemaining??0);return{result:o,expanded:s}}finally{this.pluginExpandRemaining=r}}};import{existsSync as Et,readFileSync as yi,statSync as Ci}from"node:fs";import{basename as ir,join as me,relative as ar}from"node:path";var St=2e4,Ai=4;function Ti(e){return e.length<=St?e:`${e.slice(0,St-1)}\u2026`}function Oi(e){try{let t=yi(e),n=t.toString("utf8");return{hash:A(t),length:t.length,text:Ti(n)}}catch{return null}}var sr={HOOK:"EVENT",COMMAND:"EXPLICIT_INVOCATION",MEMORY:void 0,MCP_SERVER:void 0,PLUGIN:void 0,SKILL:"UNSPECIFIED",RULE:"UNSPECIFIED",SUBAGENT:"UNSPECIFIED"};function ki(e){return e in sr?sr[e]:"UNSPECIFIED"}function be(e,t){let n=Oi(t.absolutePath);if(!n)return!1;let r=t.name??ir(t.absolutePath).replace(/\.(md|mdc|toml)$/i,""),o={kind:t.kind,name:r,path:e.homeRel(t.absolutePath),text:n.text,content_hash:n.hash,content_length:n.length,origin:t.origin,enabled:t.enabled},s=ki(t.kind);return s&&(o.trigger=s),e.push(o)}function xi(e,t,n){let r=ar(e,t).replace(/\\/g,"/");return!r||r.startsWith("..")?ir(t).replace(/\.(md|mdc|toml)$/i,""):n?r.replace(/\.(md|mdc|toml)$/i,""):r}function Y(e,t){let{dir:n,kind:r,origin:o,enabled:s,nested:i,extensions:a}=t;It(e,{walkRoot:n,currentDir:n,depth:0,kind:r,origin:o,enabled:s,nested:i,extensions:a})}function It(e,t){let{walkRoot:n,currentDir:r,depth:o,kind:s,origin:i,enabled:a,nested:c,extensions:l}=t;if(!(o>Ai))for(let u of e.readEntries(r)){if(e.atGlobalCap){e.truncated=!0;return}if(e.pluginBudgetSpent)return;if(c){if(!u.isDirectory())continue;let p=me(r,u.name,c);if(Et(p)){let _=ar(n,me(r,u.name)).replace(/\\/g,"/");be(e,{absolutePath:p,kind:s,origin:i,enabled:a,name:_||u.name});continue}It(e,{walkRoot:n,currentDir:me(r,u.name),depth:o+1,kind:s,origin:i,enabled:a,nested:c,extensions:l});continue}if(u.isDirectory()){It(e,{walkRoot:n,currentDir:me(r,u.name),depth:o+1,kind:s,origin:i,enabled:a,nested:c,extensions:l});continue}if(!u.isFile()||!l)continue;let d=u.name.toLowerCase();if(!l.some(p=>d.endsWith(p)))continue;let m=me(r,u.name);be(e,{absolutePath:m,kind:s,origin:i,enabled:a,name:xi(n,m,!0)})}}function cr(e){for(let t of e)if(Et(t))try{if(Ci(t).size>0)return t}catch{continue}return e.find(t=>Et(t))}function Ni(e){if(e.prompt||e.type==="prompt")return"prompt";let t=e.command??e.bash??e.powershell??"";return/\bnpx\b/i.test(t)?"npx":/\.(sh|bash|zsh|js|mjs|cjs|ts|py)(\s|$|"|')/i.test(t)||/^(\.\/|~\/|\/|[A-Za-z]:[\\/])/.test(t.trim())?"script":"inline"}function wi(e){return Array.isArray(e.hooks)&&e.hooks.length>0?e.hooks:[{type:e.type,command:e.command,bash:e.bash,powershell:e.powershell,prompt:e.prompt}]}function bi(e,t,n,r){let o=e.homeRel(t);for(let[s,i]of Object.entries(n))if(!(!Array.isArray(i)||e.truncated))for(let a of i){if(!a||typeof a!="object"||e.truncated)continue;let c=a;for(let l of wi(c)){if(e.truncated)return;let u=l.command??l.bash??l.prompt??l.powershell??c.powershell??"",d=Ni({type:l.type??c.type,command:l.command??c.command,bash:l.bash??c.bash,powershell:l.powershell??c.powershell,prompt:l.prompt??c.prompt}),m=typeof c.matcher=="string"?c.matcher:"",p=A(u),_=m?`${s}:${m}:${d}:${p}`:`${s}:${d}:${p}`,S=`${s}|${m}|${d}|${u}`;e.push({kind:"HOOK",name:_,path:o,content_hash:A(S),origin:r,enabled:!0,trigger:"EVENT",attributes:{event:s,...m?{matcher:m}:{},action_kind:d,action_hash:p}})}}}function ge(e,t,n){let r=e.readJson(t,{});!r?.hooks||typeof r.hooks!="object"||bi(e,t,r.hooks,n)}var lr={claude:{skillRoots:[".claude/skills"],dirs:[{dir:".claude/agents",kind:"SUBAGENT",extensions:[".md"]},{dir:".claude/commands",kind:"COMMAND",extensions:[".md"]}],memory:[".claude/CLAUDE.md"],hooks:[".claude/settings.json"],mcpJson:[".claude.json"],plugins:"claude"},cursor:{skillRoots:[".cursor/skills",".cursor/skills-cursor"],dirs:[{dir:".cursor/agents",kind:"SUBAGENT",extensions:[".md"]},{dir:".cursor/commands",kind:"COMMAND",extensions:[".md"]},{dir:".cursor/rules",kind:"RULE",extensions:[".mdc",".md"]}],memory:[".cursor/AGENTS.md"],hooks:[".cursor/hooks.json"],mcpJson:[".cursor/mcp.json"],plugins:"cursor"},codex:{skillRoots:[".agents/skills",".codex/skills"],dirs:[{dir:".codex/agents",kind:"SUBAGENT",extensions:[".toml",".md"]},{dir:".codex/prompts",kind:"COMMAND",extensions:[".md"]}],memory:[".codex/AGENTS.override.md",".codex/AGENTS.md"],hooks:[".codex/hooks.json"],mcpToml:[".codex/config.toml"]}};import{existsSync as Ui,readFileSync as vi}from"node:fs";function Pi(e){if(!e||typeof e!="object"||Array.isArray(e))return"unknown";let t=e;return typeof t.type=="string"&&t.type.length>0?t.type:typeof t.url=="string"?"http":typeof t.command=="string"?"stdio":"unknown"}function ur(e,t,n){let o=e.readJson(t,{})?.mcpServers;if(!o||typeof o!="object")return;let s=e.homeRel(t);for(let[i,a]of Object.entries(o)){if(e.truncated)return;let c=Pi(a);e.push({kind:"MCP_SERVER",name:i,path:s,content_hash:A(`${i}|${c}`),origin:n,enabled:!0,attributes:{transport:c}})}}function dr(e,t,n){if(!Ui(t))return;let r;try{r=vi(t,"utf8")}catch{return}let o=e.homeRel(t),s=/^\[mcp_servers(?:\.(\w+)|\."([^"]+)"|\.'([^']+)')\]\s*$/gm,i;for(;(i=s.exec(r))!==null;){if(e.truncated)return;let a=i[1]??i[2]??i[3];if(!a)continue;let c=r.slice(i.index+i[0].length),l=c.search(/^\[/m),u=l===-1?c:c.slice(0,l),d="unknown";/^\s*url\s*=/m.test(u)?d="http":/^\s*command\s*=/m.test(u)&&(d="stdio"),e.push({kind:"MCP_SERVER",name:a,path:o,content_hash:A(`${a}|${d}`),origin:n,enabled:!0,attributes:{transport:d}})}}import{existsSync as Li,readdirSync as Mi}from"node:fs";import{join as O}from"node:path";var fr=50;function Rt(e,t,n,r){if(!Li(t))return{componentCount:0,expandTruncated:!1};let o=e.components.length,{expanded:s}=e.withPluginExpandCap(fr,()=>{Y(e,{dir:O(t,"skills"),kind:"SKILL",origin:n,enabled:r,nested:"SKILL.md"}),Y(e,{dir:O(t,"commands"),kind:"COMMAND",origin:n,enabled:r,extensions:[".md"]}),Y(e,{dir:O(t,"agents"),kind:"SUBAGENT",origin:n,enabled:r,extensions:[".md"]})});ge(e,O(t,"hooks","hooks.json"),n),ge(e,O(t,"hooks.json"),n);let i=e.components.length-o,a=s>=fr;return{componentCount:i,expandTruncated:a}}function yt(e,t){e.push({kind:"PLUGIN",name:t.pluginKey,path:t.rowPath,content_hash:t.contentHash,origin:"user",enabled:t.enabled,attributes:{...t.marketplace?{marketplace:t.marketplace}:{},...t.version?{version:t.version}:{},scope:t.scope,component_count:t.componentCount,...t.expandTruncated?{expand_truncated:!0}:{}}})}function pr(e){let t=O(e.home,".claude/plugins/installed_plugins.json"),n=e.readJson(t,{});if(!n)return;let r=n.plugins??{},s=e.readJson(O(e.home,".claude/settings.json"),{})?.enabledPlugins??{},i=e.homeRel(t);for(let[a,c]of Object.entries(r)){if(e.truncated)return;let l=Array.isArray(c)?c:[c],u=l[0]??{},d=s[a]===!0,m=a.includes("@")?a.split("@").slice(1).join("@"):"",p=typeof u.version=="string"?u.version:"",_=typeof u.scope=="string"?u.scope:"user",S=`plugin:${a}`,k=0,T=!1;for(let b of l)if(typeof b.installPath=="string"&&b.installPath.length>0){let j=Rt(e,b.installPath,S,d);k+=j.componentCount,T=T||j.expandTruncated}yt(e,{pluginKey:a,rowPath:i,enabled:d,scope:_,version:p||void 0,marketplace:m||void 0,componentCount:k,expandTruncated:T,contentHash:A(`${a}|${p}|${_}|${d}|${k}`)})}}function Di(e){let t=e,n="";try{let r=Mi(e,{withFileTypes:!0}).filter(o=>o.isDirectory()).map(o=>o.name);if(r.length===1&&r[0])t=O(e,r[0]),n=r[0];else if(r.length>1){let o=[...r].sort(),s=o[o.length-1];s&&(t=O(e,s),n=s)}}catch{}return{installPath:t,version:n}}function mr(e){let t=[{base:O(e.home,".cursor/plugins/local"),scope:"local"},{base:O(e.home,".cursor/plugins/cache"),scope:"cache"}];for(let{base:n,scope:r}of t)if(!e.truncated)for(let o of e.readEntries(n)){if(!o.isDirectory()||e.truncated)continue;if(r==="local"){let i=o.name,a=O(n,o.name),c=`plugin:${i}`,{componentCount:l,expandTruncated:u}=Rt(e,a,c,!0);yt(e,{pluginKey:i,rowPath:e.homeRel(a),enabled:!0,scope:"local",componentCount:l,expandTruncated:u,contentHash:A(`${i}|local|${l}`)});continue}let s=o.name;for(let i of e.readEntries(O(n,s))){if(!i.isDirectory()||e.truncated)continue;let a=O(n,s,i.name),{installPath:c,version:l}=Di(a),u=`${i.name}@${s}`,d=`plugin:${u}`,{componentCount:m,expandTruncated:p}=Rt(e,c,d,!0);yt(e,{pluginKey:u,rowPath:e.homeRel(c),enabled:!0,scope:"cache",version:l||void 0,marketplace:s,componentCount:m,expandTruncated:p,contentHash:A(`${u}|${l}|${m}`)})}}}function _r(e,t,n,r){let o=lr[t];if(!o)return;let s=e.home;for(let a of o.skillRoots)Y(e,{dir:ee(s,a),kind:"SKILL",origin:n,enabled:!0,nested:"SKILL.md"});for(let a of o.dirs)Y(e,{dir:ee(s,a.dir),kind:a.kind,origin:n,enabled:!0,extensions:a.extensions});let i=cr(o.memory.map(a=>ee(s,a)));i&&be(e,{absolutePath:i,kind:"MEMORY",origin:n,enabled:!0,name:Hi(i)});for(let a of o.hooks)ge(e,ee(s,a),n);for(let a of o.mcpJson??[])ur(e,ee(s,a),n);for(let a of o.mcpToml??[])dr(e,ee(s,a),n);r&&(o.plugins==="claude"?pr(e):o.plugins==="cursor"&&mr(e))}function Ct(e,t,n){let r=new pe(t);if(_r(r,e,"user",!0),n===void 0||gr(n)===gr(t))return{components:r.components,truncated:r.truncated};let s=new pe(n,"cwd/");_r(s,e,"cwd",!1);let i=[...r.components,...s.components],a=r.truncated||s.truncated||i.length>M;return{components:i.slice(0,M),truncated:a}}function At(e,t,n={}){let r=n.truncated===!0,o=gt(e),s=new Set(e.map(u=>F(u.path,u.name)));if(n.forceFull===!0||t===void 0)return{hash:o,count:e.length,truncated:r,full:!0,upserts:e,removed:[],unchanged:!1};let a=[],c=t;for(let u of e){let d=F(u.path,u.name);c[d]!==u.content_hash&&a.push(u)}let l=[];if(!r){for(let u of Object.keys(c))if(!s.has(u)){let d=tr(u);d&&l.push(d)}}return{hash:o,count:e.length,truncated:r,full:!1,upserts:a,removed:l,unchanged:a.length===0&&l.length===0}}var Er=3e5,Fi=new Set(["HOOK","MCP_SERVER","PLUGIN"]);function Tt(e,t,n){let r=new Set(t.map(s=>F(s.path,s.name))),o=[];for(let s of e)s.text!==void 0&&(n.has(s.content_hash)||r.has(F(s.path,s.name))||o.push(s));return o}function Ot(e,t,n){let r=new Set(e);for(let s of t)r.add(s);let o=new Set(n.map(s=>s.content_hash));return[...r].filter(s=>o.has(s))}function hr(e){return Buffer.byteLength(JSON.stringify(e),"utf8")}function Sr(e){if(e.text===void 0)return e;let{text:t,...n}=e;return n}function kt(e,t=Er){let n=[],r=[];for(let u of e)Fi.has(u.kind)?n.push(u):r.push(u);r.sort((u,d)=>(u.text?.length??0)-(d.text?.length??0));let o=[...n,...r],s=[],i=2,a=0,c=0,l=[];for(let u of o){let d=s.length>0?1:0,m=hr(u)+d;if(i+m<=t){s.push(u),i+=m,u.text!==void 0&&l.push(u.content_hash);continue}if(u.text!==void 0){let p=Sr(u),_=hr(p)+d;if(i+_<=t){s.push(p),i+=_,a+=1;continue}}c+=1}return{components:s,textDeferredCount:a,droppedCount:c,textHashesSent:l}}function xt(e,t){return t.size===0?e:e.map(n=>n.text===void 0||!t.has(n.content_hash)?n:Sr(n))}var Ki={claude:{skills:".claude/skills",subagents:".claude/agents",commands:".claude/commands",memory:".claude/CLAUDE.md",settings:".claude/settings.json"},cursor:{skills:[".cursor/skills",".cursor/skills-cursor"],subagents:".cursor/agents",commands:".cursor/commands",rules:".cursor/rules",mcp:".cursor/mcp.json"},codex:{skills:[".agents/skills",".codex/skills"],subagents:".codex/agents",commands:".codex/prompts",memory:".codex/AGENTS.md",settings:".codex/config.toml"}},Gi=200,Ir=200,ji=["allow","deny","ask"],Vi=/(?<=^|[\s(,=:])(?:~|[A-Za-z]:)?[\\/][^\s,)]+/g,Nt="<path>",zi=new RegExp(`${Nt}(?:\\s+[A-Za-z.][^\\s,)]*[\\\\/][^\\s,)]*)+`,"g");function Ji(e){let t=e.replace(Vi,Nt).replace(zi,Nt);return t.length>Ir?`${t.slice(0,Ir)}...`:t}function Rr(e){let t=q(e,{}),n=[];for(let r of ji)for(let o of t.permissions?.[r]??[])typeof o=="string"&&o.length>0&&n.push({key:Ji(o),mode:r});return{model:t.model??"",permissionKeys:n}}var Wi=10,Yi=840*60*1e3,Xi="self-config-cache.json";function wt(){return y("EV_AI_HOOK_USER_SPEC")?.toLowerCase()==="off"}function Zi(e,t=Date.now()){return e===void 0||!Number.isFinite(e)?!0:t-e>=Yi}var qi={claude:["claude"],cursor:["agent","cursor-agent"],codex:["codex"]};async function Qi(e,t=C){let n=qi[e];if(!n||n.length===0)return null;let r=async o=>{let s=n[o];if(s===void 0)return null;let a=((await t(s,["--version"],2e3)).split(`
|
|
16
|
+
`)[0]??"").trim();return a||r(o+1)};return r(0)}function ea(e=yr()){return P(e,".ev-ai","agent-hook",Xi)}function ta(e){let n=[...e].sort((r,o)=>r.name.localeCompare(o.name)).map(r=>`${r.name}:${r.size}`).join(`
|
|
17
|
+
`);return A(n)}function Ue(e,t,n=!1){let r=ta(e),o=e.length;return t===r?n?{hash:r,count:o,truncated:n}:{hash:r,count:o}:n?{hash:r,count:o,entries:e,truncated:n}:{hash:r,count:o,entries:e}}function na(e){return Bi(e)?w($i(e,"utf8"),{}):{}}function ra(e,t){try{K(e,`${JSON.stringify(t)}
|
|
18
|
+
`)}catch(n){let r=n instanceof Error?n.message:String(n);g(`WARN: self-config cache write failed open: ${r}`)}}function oa(e,t,n,r){let o={...e,send_count:n};for(let s of Object.keys(t)){let i=t[s];i.entries!==void 0&&(o[s]=i.hash)}return r&&(o.user_spec_collected_at_ms=r.collectedAtMs,r.included&&(o.user_spec=r.hash,o.user_spec_components=r.componentHashes),o.user_spec_text_hashes=r.textHashes),o}async function Cr(e,t=process.cwd(),n=yr(),r={}){let o=e==="claude",s=r.gitRoot??t,i=await Qi(e),a="",c=[];if(o){let U=Rr(P(n,".claude/settings.json")),D=Rr(P(t,".claude/settings.local.json"));a=D.model||U.model,c=[...U.permissionKeys,...D.permissionKeys].slice(0,Gi)}let l=Ki[e]??{},u={present:!1,size:0},d=U=>{let D=Array.isArray(U)?U:U?[U]:[],R=[],$=!1;for(let De of D){let N=oe(P(n,De));if(R=R.concat(N.entries),$=$||N.truncated,R.length>=M){R=R.slice(0,M),$=!0;break}}return{entries:R,truncated:$}},m=ea(n),p=na(m),_=p[e]??{},S=(_.send_count??0)+1,k=S>0&&S%Wi===0,T=U=>k?void 0:_[U],b=d(l.skills),j=l.subagents?oe(P(n,l.subagents)):{entries:[],truncated:!1},Me=l.commands?oe(P(n,l.commands)):{entries:[],truncated:!1},Lt=l.rules?oe(P(n,l.rules)):{entries:[],truncated:!1},re={skills:Ue(b.entries,T("skills"),b.truncated),subagents:Ue(j.entries,T("subagents"),j.truncated),commands:Ue(Me.entries,T("commands"),Me.truncated),rules:Ue(Lt.entries,T("rules"),Lt.truncated)},x={runner_platform:e,config_scope:"user",cli_version:i,claude_version:o?i:null,model:o&&a||null,permission_keys:c,user_scope:{skills:re.skills,subagents:re.subagents,commands:re.commands,rules:re.rules,memory:l.memory?se(P(n,l.memory)):u,settings:l.settings?se(P(n,l.settings)):u,mcp:l.mcp?se(P(n,l.mcp)):u},local_settings:o?se(P(t,".claude/settings.local.json")):u},Mt=null,Dt=()=>{},Ht=r.nowMs??Date.now();if(!wt()&&Zi(_.user_spec_collected_at_ms,Ht)){let U=_.user_spec_collected_at_ms!==void 0,D=Ct(e,n),R=At(D.components,_.user_spec_components,{forceFull:!_.user_spec_components,truncated:D.truncated}),$=new Set(_.user_spec_text_hashes??[]),De=Tt(D.components,R.upserts,$),N=kt(xt([...R.upserts,...De],$));x.user_spec_hash=R.hash,x.user_spec_count=R.count,x.user_spec_truncated=R.truncated||N.droppedCount>0,(N.components.length>0||R.removed.length>0||R.full)&&(R.full&&(x.user_spec_full=!0),N.components.length>0&&(x.user_spec=N.components),R.removed.length>0&&!x.user_spec_truncated&&(x.user_spec_removed=R.removed),N.textDeferredCount>0&&(x.user_spec_text_deferred=N.textDeferredCount));let He=R.full?{}:{..._.user_spec_components??{}};if(!x.user_spec_truncated)for(let Z of R.removed)delete He[F(Z.path,Z.name)];for(let Z of N.components)He[F(Z.path,Z.name)]=Z.content_hash;Mt={hash:R.hash,componentHashes:He,textHashes:Ot($,N.textHashesSent,D.components),included:N.components.length>0||R.removed.length>0&&!x.user_spec_truncated||R.full,collectedAtMs:Ht};let Fe=await we({gitRoot:s,installationStorePath:r.installationStorePath,forceResend:U});Fe.operator&&(x.operator=Fe.operator),Dt=Fe.commit}let Kr=oa(_,re,S,Mt);return{config:x,commit:()=>{p[e]=Kr,ra(m,p),Dt()}}}function te(e,t,n){let r={installation_id:n.installationId};return n.platformAgentId&&(r.platform_agent_id=n.platformAgentId),n.sessionId&&(r.session_id=n.sessionId),n.turnId&&(r.turn_id=n.turnId),{schema_version:2,event:e,timestamp:ye(),session_id:n.sessionId||null,turn_id:n.turnId||null,installation_id:n.installationId,platform:n.runnerPlatform,platform_agent_id:n.platformAgentId||null,runner_event:n.runnerEvent||null,agent_hook_version:Ke,host_arch:process.arch,node_version:process.version,correlation:r,payload:t}}import{existsSync as Ar}from"node:fs";import{spawn as Tr}from"node:child_process";import{basename as sa}from"node:path";import{fileURLToPath as ia}from"node:url";var Ut="__post",ve="__work";function aa(e,t){let n=e.payload,r=n&&typeof n=="object"&&!Array.isArray(n)?Object.keys(n):[],o=e.correlation&&typeof e.correlation=="object"?Object.keys(e.correlation):[];return JSON.stringify({event:e.event,schema_version:e.schema_version,agent_hook_version:e.agent_hook_version,host_arch:e.host_arch,node_version:e.node_version,build_ms:e.build_ms,body_bytes:t,correlation_keys:o,payload_keys:r})}function Or(e){switch(e){case"session_start":return Kt;case"session_end":return Gt;case"tool_invoked":case"skill_invoked":return Be;default:return Be}}function ca(e,t,n){return`${JSON.stringify({url:e,timeoutMs:t})}
|
|
19
|
+
${n}`}function kr(e,t=[],n=process.execPath,r=import.meta.url,o=Ar){if(sa(n)===Re)return{command:n,args:[e,...t]};let s=ia(r);return o(s)?{command:n,args:[s,e,...t]}:{command:n,args:[e,...t]}}function la(e=process.execPath,t=import.meta.url,n=Ar){return kr(Ut,[],e,t,n)}function ua(e){let t=e.indexOf(`
|
|
20
|
+
`);if(t<0)return null;let n;try{n=JSON.parse(e.slice(0,t))}catch{return null}return{meta:n,body:e.slice(t+1)}}async function xr(e,t=fetch){let n=await e(),r=ua(n);if(!r)return;let{meta:o,body:s}=r,i={"Content-Type":"application/json"};try{await t(o.url,{method:"POST",headers:i,body:s,signal:AbortSignal.timeout(Number(o.timeoutMs))})}catch{}}async function da(e,t,n){let r=Or(e);g(`POST event=${e} url=${nt(n)} size=${t.length} platform=${process.platform}`);let o={"Content-Type":"application/json"},s=Date.now();try{let i=await fetch(n,{method:"POST",headers:o,body:t,signal:AbortSignal.timeout(r)}),a=Date.now()-s;if(i.ok)return g(`POST outcome=ok elapsed_ms=${a} http=${i.status}`),!0;let c=(await i.text()).slice(0,200).replace(/[\n\r]/g,"");return g(`POST outcome=fail elapsed_ms=${a} http=${i.status} body=${c}`),!1}catch(i){let a=Date.now()-s,c=i instanceof Error?i.message:String(i);return g(`POST outcome=fail elapsed_ms=${a} http=000 body=${c}`),!1}}async function Nr(e,t,n,r,o){try{let s=r(e,t,{detached:!0,stdio:["pipe","ignore","ignore"],windowsHide:!0});s.on("error",()=>{}),s.stdin.on("error",()=>{});let i=!1;return await new Promise(a=>{let c=setTimeout(()=>{if(!i){g(`WARN: ${o} stdin handoff timed out \u2014 continuing fail-open`);try{s.stdin.destroy()}catch{}}a()},jt),l=()=>{i=!0,clearTimeout(c),a()};s.stdin.end(n,()=>l()),s.stdin.once("error",()=>l())}),s.unref(),s}catch(s){let i=s instanceof Error?s.message:String(s);return g(`WARN: ${o} spawn failed open: ${i}`),null}}async function fa(e,t,n,r=Tr,o=la){let s=Or(e),i=ca(n,s,t),{command:a,args:c}=o();return Nr(a,c,i,r,"detached post")}async function wr(e,t,n=Tr,r=kr){let{command:o,args:s}=r(ve,t);return Nr(o,s,e,n,"detached work")}async function ne(e,t,n,r,o,s){if(!o)return g("WARN: collector URL missing \u2014 pass --url on the hook command or set collector_url in manifest"),!1;if(!Ae(o))return g(`WARN: collector URL blocked (https required): ${nt(o)}`),!1;let i=r(e,t,n);s!==void 0&&(i.build_ms=Math.max(0,Date.now()-s));let a=`${JSON.stringify(i)}
|
|
21
|
+
`,c=y("EV_AI_HOOK_DEBUG");c==="full"?g(`DEBUG envelope=${JSON.stringify(i)}`):c==="1"&&g(`DEBUG summary=${aa(i,Buffer.byteLength(a,"utf8"))}`);let l=process.argv.includes(ve),u=y("EV_AI_HOOK_SYNC")==="1";return xe(n.runnerEvent,n.runnerPlatform)||l||u?da(e,a,o):(await fa(e,a,o),!1)}import{relative as pa,resolve as Pe,sep as vt}from"node:path";var ma=["session_id","conversation_id","turn_id","generation_id","prompt.id","prompt_id","hook_event_name","event","source","status","stop_reason","reason","tool_name","tool","tool_use_id","skill_name","command_name","expansion_type","command_source","permission_mode","model","model_id","agent_id","agent_type","subagent_id","subagent_type","subagent_model","is_parallel_worker","effort","effort.level","duration_ms","duration","sandbox","failure_type","is_interrupt"];function ga(e){return e.capture_hook_input==="full"?!0:e.capture_hook_input==="allowlist"?!1:y("EV_AI_HOOK_CAPTURE_FULL_INPUT")==="1"}function _a(e){let t={};for(let n of ma){let r=J(e,n);r!==void 0&&(t[n]=r)}return t}function ha(e,t){if(typeof e!="string"||e.length===0||!t)return null;let n=Pe(e),r=Pe(t),o=pa(r,n);return!o||o==="."?".":o.startsWith(`..${vt}`)||o===".."||Pe(r,o)!==n?null:o.split(vt).join("/")}function Ea(e){return typeof e!="string"||e.length===0?null:Pe(e).split(vt).join("/")}function br(e,t,n){let r=Ea(t.cwd);r!==null&&(e.cwd=r);let o=n.inGitRepo===!0&&n.gitRoot!==void 0?ha(t.cwd,n.gitRoot):null;o!==null&&(e.cwd_relative=o)}function Ur(e,t){let n=JSON.stringify(e),r=Buffer.byteLength(n,"utf8");if(r<=t)return e;let o=Object.entries(e).filter(([i,a])=>!i.startsWith("_")&&(typeof a=="string"||typeof a=="number"||typeof a=="boolean")).sort((i,a)=>Buffer.byteLength(JSON.stringify(i[1]),"utf8")-Buffer.byteLength(JSON.stringify(a[1]),"utf8")),s={_truncated:!0,_original_bytes:r};for(let[i,a]of o){let c={...s,[i]:a};if(Buffer.byteLength(JSON.stringify(c),"utf8")>t)break;s[i]=a}return s}function _e(e,t,n={}){if(ga(t)){let o={...e};return delete o.cwd,delete o.transcript_path,br(o,e,n),Ur(o,zt)}let r=_a(e);return br(r,e,n),Ur(r,Vt)}import{createReadStream as Sa}from"node:fs";import{stat as Ia}from"node:fs/promises";import{basename as Ra,resolve as ya}from"node:path";import{createInterface as Ca}from"node:readline";var Aa=1024*1024;function Ta(e){let t=e.replace(/\\/g,"/");return t.includes("/.claude/projects/")&&Ra(t).endsWith(".jsonl")}async function vr(e){if(!e||!Ta(e))return null;try{let t=ya(e),n=await Ia(t);if(!n.isFile())return null;let r=Math.max(0,n.size-Aa),o=[],s=Ca({input:Sa(t,{encoding:"utf8",start:r}),crlfDelay:1/0});for await(let i of s)i.length!==0&&o.push(i);r>0&&o.length>0&&o.shift();for(let i=o.length-1;i>=0;i--){let a=o[i];if(a)try{let c=JSON.parse(a);if(c.type!=="assistant")continue;let l=c.message;if(!l||typeof l!="object")continue;let u=l.model;if(typeof u=="string"&&u.length>0)return u}catch{continue}}return null}catch{return null}}function Ee(e){return{sessionId:e.sessionId,turnId:e.turnId,installationId:e.manifest.installationId,runnerPlatform:e.runnerPlatform,platformAgentId:e.platformAgentId,runnerEvent:e.runnerEvent}}function Le(e){return{gitRoot:e.manifest.gitRoot,inGitRepo:e.manifest.inGitRepo}}var Oa=new Set([...Object.values(lt),".github"]);function ka(e,t,n){if(e===null||t===null||n===null||!(/^mcp__.+?__.+$/i.test(e)||/^MCP:[^:]+:.+$/i.test(e)||e.toLowerCase()===`mcp:${t.toLowerCase()}`))return;let o=n.indexOf(":");if(o<=0||o===n.length-1)return;let s=n.slice(o+1),i=s.replaceAll("\\","/").split("/").at(-1);if(!(i===void 0||!Oa.has(i)))try{return(0,G.buildComponentReference)({installationRootExternalKey:n,installableKind:G.ComponentKind.INTERFACE,sourcePath:s,nativeKey:t})}catch{return}}function xa(...e){for(let t of e)if(t)return t;return null}function L(e,t,n){if(e.status==="fulfilled")return e.value;let r=e.reason instanceof Error?e.reason.message:String(e.reason);return g(`WARN: ${n} failed open: ${r}`),t}function Na(e){let t={present:!1,size:0},n={hash:"",count:0};return{config:{runner_platform:e,config_scope:"user",cli_version:null,claude_version:null,model:null,permission_keys:[],user_scope:{skills:n,subagents:n,commands:n,rules:n,memory:t,settings:t,mcp:t},local_settings:t},commit:()=>{}}}function wa(e,t){return{runner_platform:e,config_scope:"user",...t?{operator:t}:{}}}var X=new Set,he=null;async function Pr(e){if(wt())return;let t=e.manifest.installationId,n=e.manifest.installationStorePath;if(X.has(t))return;if(!ht(n)){X.add(t);return}let r=ae({sessionId:e.sessionId,hostname:ce()});if(rr(r)){if(he){await he;return}he=(async()=>{if(X.has(t)||!ht(n)){X.add(t);return}if(!Sn(n)){X.add(t);return}let o=!1;try{let s=Date.now(),{gitRoot:i}=e.manifest,a=String(e.runnerPlatform),[c,l,u,d,m]=await Promise.allSettled([fe(i),Xe(),ut(r),Ze(),we({gitRoot:i,installationStorePath:n,forceResend:!1})]),p=L(c,null,"gitSnapshot"),_=L(l,"","detectVirt"),S=L(u,null,"probeCloud"),k=L(d,{},"hostEnv"),T=L(m,{commit:()=>{}},"resolveOperatorForSend");await Se(e,i,p);let b={identity:{host:ce(),context:r,virt:_||null,cloud:S,git:p},host_env:k,env_vars:mt(),self_config:wa(a,T.operator),run_meta:{trigger:"cloud_identity_bootstrap"}};o=!!await ne("session_start",b,Ee(e),te,e.manifest.collectorUrl,s),o&&(T.commit(),X.add(t))}finally{In(n)}})().finally(()=>{he=null}),await he}}async function Se(e,t,n){try{let r=n===void 0?await fe(t):n;e.platformAgentId=await Xn(e.manifest.manifest,e.platformAgentId,String(e.runnerPlatform),t,r,e.manifest.installationStorePath,e.manifest.repoKey)}catch(r){let o=r instanceof Error?r.message:String(r);g(`WARN: derivePlatformAgentId failed open: ${o}`)}}async function ba(e){let t=Date.now(),{gitRoot:n}=e.manifest,r=ae({sessionId:e.sessionId,hostname:ce()}),o=String(e.runnerPlatform),[s,i,a,c,l,u]=await Promise.allSettled([fe(n),Xe(),ut(r),Ze(),pt(e.manifest.manifest,n,o),Cr(o,n,void 0,{installationStorePath:e.manifest.installationStorePath,gitRoot:n})]),d=L(s,null,"gitSnapshot"),m=L(i,"","detectVirt"),p=L(a,null,"probeCloud"),_=L(c,{},"hostEnv"),S=L(l,[],"mcpDeclared"),k=L(u,Na(o),"selfConfig"),T=k.config;await Se(e,n,d);let b=f(e.hookInput,"model");b&&(T.model=b);let j={identity:{host:ce(),context:r,virt:m||null,cloud:p,git:d},host_env:_,env_vars:mt(),mcp:{declared:S},self_config:T,run_meta:{trigger:e.hookSource||"startup"},hook_input:_e(e.hookInput,e.manifest.manifest,Le(e))};await ne("session_start",j,Ee(e),te,e.manifest.collectorUrl,t)&&(k.commit(),X.add(e.manifest.installationId))}async function Ua(e){let t=Date.now(),{gitRoot:n}=e.manifest;await Se(e,n);let r=xa(f(e.hookInput,"status"),f(e.hookInput,"stop_reason"),f(e.hookInput,"reason"),at(f(e.hookInput,"error"))),o=e.runnerPlatform==="claude"?await vr(f(e.hookInput,"transcript_path")):null,s=_e(e.hookInput,e.manifest.manifest,Le(e));o&&(s.model=o),await ne("session_end",{status:r,...o?{model:o}:{},hook_input:s},Ee(e),te,e.manifest.collectorUrl,t)}async function va(e){let t=Date.now(),n=vn(e.hookInput);if(n.length===0)return;await Pr(e);let{gitRoot:r}=e.manifest;await Se(e,r);let o=_e(e.hookInput,e.manifest.manifest,Le(e)),s=Ee(e),i=Te(e.hookInput.tool_input),a=r.replaceAll("\\","/").replace(/\/$/,""),c=i?.replaceAll("\\","/"),l=c===void 0?null:c.startsWith(`${a}/`)?c.slice(a.length+1):c.startsWith("/")?null:c;await Promise.all(n.map(u=>{let d;if(l!==null&&rt(l)?.toLowerCase()===u.toLowerCase()&&e.platformAgentId){let m=(0,G.nativeKeyForSkillPath)(l);if(m!==null)try{d=(0,G.buildComponentReference)({installationRootExternalKey:e.platformAgentId,installableKind:G.ComponentKind.SKILL,sourcePath:l,nativeKey:m})}catch{d=void 0}}return ne("tool_invoked",{tool_name:"Skill",skill_name:u,...d===void 0?{}:{component_reference:d},success:null,duration_ms:null,hook_input:o},s,te,e.manifest.collectorUrl,t)}))}async function Pa(e){let t=Date.now();await Pr(e);let{gitRoot:n}=e.manifest;await Se(e,n);let{toolName:r,skillName:o}=Hn(e.hookInput,e.runnerEvent),s=Bn(e.hookInput),i=Ln(e.runnerEvent),a=i===!1?$n(e.hookInput,e.runnerEvent):null,c=await pt(e.manifest.manifest,e.manifest.gitRoot,String(e.runnerPlatform)).catch(()=>[]),{mcpServer:l,mcpTool:u}=Kn(r,c.map(p=>p.name)),d=ka(r,l,e.platformAgentId),m=Fn(e.hookInput);await ne("tool_invoked",{tool_name:r,skill_name:o,success:i,duration_ms:s,...a?{failure_reason:a}:{},...l?{mcp_server:l}:{},...u?{mcp_tool:u}:{},...d?{component_reference:d}:{},...m?{subagent_type:m}:{},hook_input:_e(e.hookInput,e.manifest.manifest,Le(e))},Ee(e),te,e.manifest.collectorUrl,t)}async function Lr(e){switch(e.internalEvent){case"session_start":await ba(e);return;case"session_end":await Ua(e);return;case"skill_invoked":await va(e);return;case"tool_invoked":await Pa(e);return;default:return}}function Mr(e){return e!=="session_start"&&e!=="session_end"&&e!=="tool_invoked"&&e!=="skill_invoked"&&e!==""}import{existsSync as Pt,readFileSync as La}from"node:fs";import{dirname as Ma,join as Dr,relative as Da}from"node:path";var Hr=[$t,".cursor/ev-ai-runtime-report.json",".codex/ev-ai-runtime-report.json"];async function Ha(e=process.cwd(),t){let n=y("EV_AI_HOOK_MANIFEST");if(n&&Pt(n))return n;let r=t??await We(e);for(let o of Hr){let s=Dr(r,o);if(Pt(s))return s}for(let o of Hr){let s=Dr(e,o);if(Pt(s))return s}}async function Fa(e,t){let n=t??await We(Ma(e)),r=Da(n,e),o=await v("git",["ls-files","--error-unmatch",r],2e3,{cwd:n});return o.ok?!0:o.code===1?!1:(g(`WARN: git ls-files failed for manifest ${e} (code=${String(o.code)}); treating as tracked`),!0)}function Ba(e){let t=La(e,"utf8");return w(t,{})}function $a(){return{schema_version:2,mcp_servers:[]}}async function Fr(e=process.cwd(),t={}){let{root:n,inGitRepo:r}=await Je(e),o=await Ha(e,n),s=o?Ba(o):$a();delete s.installation_id;let i=o?await Fa(o,n):!1;s.capture_hook_input==="full"&&o&&i&&(g(`WARN: ignoring capture_hook_input=full in git-tracked manifest ${o}; use EV_AI_HOOK_CAPTURE_FULL_INPUT=1 or an untracked operator manifest`),delete s.capture_hook_input);let{installationId:a,storePath:c,repoKey:l}=await An(n,{sessionId:t.sessionId});return{manifestPath:o??c,manifest:s,installationId:a,installationStorePath:c,repoKey:l,collectorUrl:Nn(s),platformAgentId:s.platform_agent_id??"",gitRoot:n,inGitRepo:r}}async function Br(e,t,n,r){let o=t??await ze($e),s=w(o,{}),i=f(s,"session_id")||f(s,"conversation_id"),a=await Fr(process.cwd(),{sessionId:i});if(!a)return;r&&(a.collectorUrl=r);let c=Mn(s,a.manifest.platform,n),l=Dn(e,c.runnerEvent);if(!l){g(`WARN: unknown hook event '${c.runnerEvent}'; skipping telemetry`);return}let u={hookInput:s,sessionId:c.sessionId,turnId:c.turnId,runnerEvent:c.runnerEvent,runnerPlatform:c.runnerPlatform,hookSource:c.hookSource,internalEvent:l,manifest:a,platformAgentId:a.platformAgentId};if(Mr(l)){g(`WARN: unsupported internal event '${l}'`);return}await Lr(u)}function Ka(e,t){if(y("EV_AI_HOOK_SYNC")==="1")return!0;let n=ke(e),r=w(t,{}),o=n.event??(f(r,"hook_event_name")||f(r,"event")),s=ue(r,o,void 0,n.runner);return xe(o,s)}async function $r(e=process.argv.slice(2)){if(e[0]===Ut){try{await xr(Ve)}catch{}return 0}if(e[0]===ve){try{let t=ke(e.slice(1)),n=await Ve(),r=w(n,{}),o=t.event??(f(r,"hook_event_name")||f(r,"event"));if(it(t.runner,r,o))return 0;await Br(t.event,n,t.runner,st(t))}catch(t){let n=t instanceof Error?t.message:String(t);g(`WARN: detached work failed open: ${n}`)}return 0}try{let t=await ze($e),n=ke(e),r=st(n),o=w(t,{}),s=n.event??(f(o,"hook_event_name")||f(o,"event"));if(it(n.runner,o,s)||!Yn(o,s,n.runner))return 0;Ka(e,t)?await Br(n.event,t,n.runner,r):await wr(t,e)}catch(t){let n=t instanceof Error?t.message:String(t);g(`WARN: hook failed open: ${n}`)}finally{Qt()}return 0}$r().then(e=>{process.exit(e)}).catch(e=>{let t=e instanceof Error?e.message:String(e);process.stderr.write(`[ev-ai-agent-hook] ${t}
|
|
16
22
|
`),process.exit(1)});
|
package/dist/plugin-hooks.mjs
CHANGED
|
@@ -9,7 +9,7 @@ var PROJECT_HOOK_BINARY_RELATIVE = `.ev-ai/agent-hook/${HOOK_BINARY_NAME}`;
|
|
|
9
9
|
var HOOK_INPUT_ALLOWLIST_MAX_BYTES = 4 * 1024;
|
|
10
10
|
var HOOK_INPUT_FULL_MAX_BYTES = 32 * 1024;
|
|
11
11
|
var HOOK_INPUT_MCP_MAX_BYTES = 4 * 1024;
|
|
12
|
-
var PACKAGE_VERSION = "1.0.
|
|
12
|
+
var PACKAGE_VERSION = "1.0.8";
|
|
13
13
|
var NPX_PACKAGE_SPEC = `@ev-ai/agent-hook@${PACKAGE_VERSION}`;
|
|
14
14
|
var HOOK_STATUS_MESSAGE = "ev-ai runtime report";
|
|
15
15
|
|
|
@@ -65,6 +65,11 @@ var CURSOR_WIRED_HOOK_EVENTS = [
|
|
|
65
65
|
"preToolUse",
|
|
66
66
|
"postToolUse",
|
|
67
67
|
"postToolUseFailure",
|
|
68
|
+
"beforeShellExecution",
|
|
69
|
+
"afterShellExecution",
|
|
70
|
+
"beforeReadFile",
|
|
71
|
+
"afterFileEdit",
|
|
72
|
+
"beforeMCPExecution",
|
|
68
73
|
"subagentStart",
|
|
69
74
|
"subagentStop",
|
|
70
75
|
"stop"
|