@ironbee-ai/cli 0.5.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/clients/claude/hooks/require-verification.d.ts.map +1 -1
  3. package/dist/clients/claude/hooks/require-verification.js +21 -2
  4. package/dist/clients/claude/hooks/require-verification.js.map +1 -1
  5. package/dist/clients/claude/hooks/session-end.d.ts.map +1 -1
  6. package/dist/clients/claude/hooks/session-end.js +4 -0
  7. package/dist/clients/claude/hooks/session-end.js.map +1 -1
  8. package/dist/clients/claude/hooks/session-start.d.ts.map +1 -1
  9. package/dist/clients/claude/hooks/session-start.js +6 -1
  10. package/dist/clients/claude/hooks/session-start.js.map +1 -1
  11. package/dist/clients/claude/hooks/track-action.d.ts +25 -4
  12. package/dist/clients/claude/hooks/track-action.d.ts.map +1 -1
  13. package/dist/clients/claude/hooks/track-action.js +145 -25
  14. package/dist/clients/claude/hooks/track-action.js.map +1 -1
  15. package/dist/clients/claude/hooks/verify-gate.d.ts.map +1 -1
  16. package/dist/clients/claude/hooks/verify-gate.js +5 -0
  17. package/dist/clients/claude/hooks/verify-gate.js.map +1 -1
  18. package/dist/clients/claude/index.d.ts.map +1 -1
  19. package/dist/clients/claude/index.js +18 -1
  20. package/dist/clients/claude/index.js.map +1 -1
  21. package/dist/clients/claude/util.d.ts +74 -0
  22. package/dist/clients/claude/util.d.ts.map +1 -0
  23. package/dist/clients/claude/util.js +352 -0
  24. package/dist/clients/claude/util.js.map +1 -0
  25. package/dist/clients/cursor/hooks/require-verification.d.ts.map +1 -1
  26. package/dist/clients/cursor/hooks/require-verification.js +18 -2
  27. package/dist/clients/cursor/hooks/require-verification.js.map +1 -1
  28. package/dist/clients/cursor/hooks/session-end.d.ts.map +1 -1
  29. package/dist/clients/cursor/hooks/session-end.js +4 -0
  30. package/dist/clients/cursor/hooks/session-end.js.map +1 -1
  31. package/dist/clients/cursor/hooks/session-start.d.ts.map +1 -1
  32. package/dist/clients/cursor/hooks/session-start.js +4 -1
  33. package/dist/clients/cursor/hooks/session-start.js.map +1 -1
  34. package/dist/clients/cursor/hooks/track-action.d.ts +30 -8
  35. package/dist/clients/cursor/hooks/track-action.d.ts.map +1 -1
  36. package/dist/clients/cursor/hooks/track-action.js +179 -52
  37. package/dist/clients/cursor/hooks/track-action.js.map +1 -1
  38. package/dist/clients/cursor/hooks/verify-gate.d.ts.map +1 -1
  39. package/dist/clients/cursor/hooks/verify-gate.js +4 -0
  40. package/dist/clients/cursor/hooks/verify-gate.js.map +1 -1
  41. package/dist/clients/cursor/index.d.ts.map +1 -1
  42. package/dist/clients/cursor/index.js +13 -2
  43. package/dist/clients/cursor/index.js.map +1 -1
  44. package/dist/clients/cursor/util.d.ts +52 -0
  45. package/dist/clients/cursor/util.d.ts.map +1 -0
  46. package/dist/clients/cursor/util.js +264 -0
  47. package/dist/clients/cursor/util.js.map +1 -0
  48. package/dist/commands/hook.js +1 -2
  49. package/dist/commands/hook.js.map +1 -1
  50. package/dist/commands/process-job-file.d.ts +10 -0
  51. package/dist/commands/process-job-file.d.ts.map +1 -0
  52. package/dist/commands/process-job-file.js +19 -0
  53. package/dist/commands/process-job-file.js.map +1 -0
  54. package/dist/commands/queue.d.ts +12 -0
  55. package/dist/commands/queue.d.ts.map +1 -0
  56. package/dist/commands/queue.js +495 -0
  57. package/dist/commands/queue.js.map +1 -0
  58. package/dist/hooks/core/actions.d.ts +73 -2
  59. package/dist/hooks/core/actions.d.ts.map +1 -1
  60. package/dist/hooks/core/actions.js +36 -2
  61. package/dist/hooks/core/actions.js.map +1 -1
  62. package/dist/hooks/core/session-state.d.ts +13 -0
  63. package/dist/hooks/core/session-state.d.ts.map +1 -1
  64. package/dist/hooks/core/session-state.js +21 -0
  65. package/dist/hooks/core/session-state.js.map +1 -1
  66. package/dist/hooks/core/verify-gate.d.ts.map +1 -1
  67. package/dist/hooks/core/verify-gate.js +13 -5
  68. package/dist/hooks/core/verify-gate.js.map +1 -1
  69. package/dist/index.js +12 -3
  70. package/dist/index.js.map +1 -1
  71. package/dist/lib/collector.d.ts +62 -3
  72. package/dist/lib/collector.d.ts.map +1 -1
  73. package/dist/lib/collector.js +107 -35
  74. package/dist/lib/collector.js.map +1 -1
  75. package/dist/lib/config.d.ts +72 -8
  76. package/dist/lib/config.d.ts.map +1 -1
  77. package/dist/lib/config.js +40 -0
  78. package/dist/lib/config.js.map +1 -1
  79. package/dist/queue/dead-letter.d.ts +26 -0
  80. package/dist/queue/dead-letter.d.ts.map +1 -0
  81. package/dist/queue/dead-letter.js +233 -0
  82. package/dist/queue/dead-letter.js.map +1 -0
  83. package/dist/queue/drain.d.ts +36 -0
  84. package/dist/queue/drain.d.ts.map +1 -0
  85. package/dist/queue/drain.js +170 -0
  86. package/dist/queue/drain.js.map +1 -0
  87. package/dist/queue/flush.d.ts +64 -0
  88. package/dist/queue/flush.d.ts.map +1 -0
  89. package/dist/queue/flush.js +119 -0
  90. package/dist/queue/flush.js.map +1 -0
  91. package/dist/queue/handlers/send-event.d.ts +23 -0
  92. package/dist/queue/handlers/send-event.d.ts.map +1 -0
  93. package/dist/queue/handlers/send-event.js +131 -0
  94. package/dist/queue/handlers/send-event.js.map +1 -0
  95. package/dist/queue/index.d.ts +30 -0
  96. package/dist/queue/index.d.ts.map +1 -0
  97. package/dist/queue/index.js +71 -0
  98. package/dist/queue/index.js.map +1 -0
  99. package/dist/queue/paths.d.ts +40 -0
  100. package/dist/queue/paths.d.ts.map +1 -0
  101. package/dist/queue/paths.js +107 -0
  102. package/dist/queue/paths.js.map +1 -0
  103. package/dist/queue/process-file.d.ts +22 -0
  104. package/dist/queue/process-file.d.ts.map +1 -0
  105. package/dist/queue/process-file.js +257 -0
  106. package/dist/queue/process-file.js.map +1 -0
  107. package/dist/queue/register-handlers.d.ts +26 -0
  108. package/dist/queue/register-handlers.d.ts.map +1 -0
  109. package/dist/queue/register-handlers.js +36 -0
  110. package/dist/queue/register-handlers.js.map +1 -0
  111. package/dist/queue/registry.d.ts +42 -0
  112. package/dist/queue/registry.d.ts.map +1 -0
  113. package/dist/queue/registry.js +36 -0
  114. package/dist/queue/registry.js.map +1 -0
  115. package/dist/queue/snapshot.d.ts +16 -0
  116. package/dist/queue/snapshot.d.ts.map +1 -0
  117. package/dist/queue/snapshot.js +39 -0
  118. package/dist/queue/snapshot.js.map +1 -0
  119. package/dist/queue/spawn.d.ts +15 -0
  120. package/dist/queue/spawn.d.ts.map +1 -0
  121. package/dist/queue/spawn.js +45 -0
  122. package/dist/queue/spawn.js.map +1 -0
  123. package/dist/queue/submit.d.ts +19 -0
  124. package/dist/queue/submit.d.ts.map +1 -0
  125. package/dist/queue/submit.js +94 -0
  126. package/dist/queue/submit.js.map +1 -0
  127. package/dist/queue/types.d.ts +77 -0
  128. package/dist/queue/types.d.ts.map +1 -0
  129. package/dist/queue/types.js +83 -0
  130. package/dist/queue/types.js.map +1 -0
  131. package/dist/queue/worker-log.d.ts +21 -0
  132. package/dist/queue/worker-log.d.ts.map +1 -0
  133. package/dist/queue/worker-log.js +140 -0
  134. package/dist/queue/worker-log.js.map +1 -0
  135. package/package.json +1 -1
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Claude — small client-specific utilities
3
+ *
4
+ * Bundles four Claude-only helpers in one file (provisional grouping):
5
+ *
6
+ * - `getClaudeUserEmail()` : OAuth email lookup from `~/.claude.json`
7
+ * - `extractMcpServerName(name)` : parse `mcp__<server>__<tool>` for the server
8
+ * - `extractClaudeToolInput(name, input)` : per-tool whitelist projection
9
+ * - `classifyTool(name, input)` : normalize a Claude tool invocation
10
+ * into `{ tool_type, tool_name, mcp_server }`
11
+ *
12
+ * They're co-located here (rather than `src/lib/`) because each one
13
+ * encodes Claude Code's wire conventions or storage layout — Cursor
14
+ * needs none of them. If any helper grows substantially, split it back
15
+ * into its own file.
16
+ */
17
+ /**
18
+ * Returns the Claude OAuth-authenticated user's email, or undefined if:
19
+ * - `~/.claude.json` does not exist (e.g., Claude Code never logged in)
20
+ * - the file is malformed
21
+ * - `oauthAccount.emailAddress` is absent (API-key / 3rd-party provider auth)
22
+ */
23
+ export declare function getClaudeUserEmail(): string | undefined;
24
+ /**
25
+ * Extract the MCP server name from a Claude-style tool name.
26
+ *
27
+ * "mcp__browser-devtools__bdt_navigation_go-to" → "browser-devtools"
28
+ * "mcp__slack__read_channel" → "slack"
29
+ * "Read" / "Bash" / "Edit" → null (not MCP)
30
+ * "mcp__" → null (malformed)
31
+ * "" → null
32
+ *
33
+ * Cursor uses a different prefix (`MCP:<tool>`) with no server segment —
34
+ * the Cursor adapter doesn't call this and the function would always
35
+ * return null on Cursor input by design.
36
+ */
37
+ export declare function extractMcpServerName(toolName: string | undefined): string | null;
38
+ /**
39
+ * Build the safe `tool_input` projection for a Claude tool invocation.
40
+ *
41
+ * See `docs/claude-builtin-tool-schemas.md` for the source schema for each
42
+ * tool. Returns:
43
+ * - the projected object for any known Claude built-in tool
44
+ * - `undefined` for any MCP / unknown tool (caller handles those flows)
45
+ */
46
+ export declare function extractClaudeToolInput(rawToolName: string, toolInput: unknown): unknown;
47
+ /**
48
+ * Normalizes Claude Code's raw `tool_name` + `tool_input` into the unified
49
+ * `tool_call` shape used downstream. Cursor has its own classifier under
50
+ * `src/clients/cursor/util.ts:classifyTool` — keeping these separate so
51
+ * each adapter only reasons about its own wire conventions.
52
+ *
53
+ * Raw inputs handled here:
54
+ * - Native: `"Read"` / `"Bash"` / `"Edit"` / …
55
+ * - MCP: `"mcp__<server>__<tool>"`
56
+ * - Skill: `tool_name="Skill"`, `tool_input.skill="<skill>"`
57
+ * - Sub-agent spawn: `tool_name="Agent"` | `"Task"` (legacy),
58
+ * `tool_input.subagent_type="<type>"`
59
+ */
60
+ export type ToolType = "mcp" | "skill" | "sub_agent" | null;
61
+ export interface ClassifiedTool {
62
+ tool_type: ToolType;
63
+ tool_name: string;
64
+ mcp_server: string | null;
65
+ }
66
+ /**
67
+ * Classify a Claude tool invocation. If `tool_input` is malformed or
68
+ * missing the expected discriminator for a typed bucket (`Skill` without
69
+ * `skill`, `Agent` without `subagent_type`), the classifier still assigns
70
+ * the bucket (so downstream can filter on `tool_type`) but falls back to
71
+ * the raw tool name — it never silently drops the bucket tag.
72
+ */
73
+ export declare function classifyTool(rawToolName: string, toolInput: unknown): ClassifiedTool;
74
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/clients/claude/util.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA2CH;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAgBvD;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAWhF;AAqGD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAiIvF;AAMD;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,WAAW,GAAG,IAAI,CAAC;AAE5D,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,QAAQ,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAOD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,cAAc,CA2CpF"}
@@ -0,0 +1,352 @@
1
+ "use strict";
2
+ /**
3
+ * Claude — small client-specific utilities
4
+ *
5
+ * Bundles four Claude-only helpers in one file (provisional grouping):
6
+ *
7
+ * - `getClaudeUserEmail()` : OAuth email lookup from `~/.claude.json`
8
+ * - `extractMcpServerName(name)` : parse `mcp__<server>__<tool>` for the server
9
+ * - `extractClaudeToolInput(name, input)` : per-tool whitelist projection
10
+ * - `classifyTool(name, input)` : normalize a Claude tool invocation
11
+ * into `{ tool_type, tool_name, mcp_server }`
12
+ *
13
+ * They're co-located here (rather than `src/lib/`) because each one
14
+ * encodes Claude Code's wire conventions or storage layout — Cursor
15
+ * needs none of them. If any helper grows substantially, split it back
16
+ * into its own file.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.getClaudeUserEmail = getClaudeUserEmail;
20
+ exports.extractMcpServerName = extractMcpServerName;
21
+ exports.extractClaudeToolInput = extractClaudeToolInput;
22
+ exports.classifyTool = classifyTool;
23
+ const fs_1 = require("fs");
24
+ const os_1 = require("os");
25
+ const path_1 = require("path");
26
+ const logger_1 = require("../../lib/logger");
27
+ /**
28
+ * Returns the Claude OAuth-authenticated user's email, or undefined if:
29
+ * - `~/.claude.json` does not exist (e.g., Claude Code never logged in)
30
+ * - the file is malformed
31
+ * - `oauthAccount.emailAddress` is absent (API-key / 3rd-party provider auth)
32
+ */
33
+ function getClaudeUserEmail() {
34
+ const path = (0, path_1.join)((0, os_1.homedir)(), ".claude.json");
35
+ if (!(0, fs_1.existsSync)(path)) {
36
+ return undefined;
37
+ }
38
+ try {
39
+ const config = JSON.parse((0, fs_1.readFileSync)(path, "utf-8"));
40
+ const email = config.oauthAccount?.emailAddress;
41
+ if (typeof email === "string" && email.length > 0) {
42
+ return email;
43
+ }
44
+ return undefined;
45
+ }
46
+ catch (e) {
47
+ logger_1.logger.debug(`failed to read ~/.claude.json: ${e instanceof Error ? e.message : e}`);
48
+ return undefined;
49
+ }
50
+ }
51
+ // ─────────────────────────────────────────────────────────────────────────
52
+ // 2. MCP server-name parser (Claude `mcp__<server>__<tool>` convention)
53
+ // ─────────────────────────────────────────────────────────────────────────
54
+ /**
55
+ * Extract the MCP server name from a Claude-style tool name.
56
+ *
57
+ * "mcp__browser-devtools__bdt_navigation_go-to" → "browser-devtools"
58
+ * "mcp__slack__read_channel" → "slack"
59
+ * "Read" / "Bash" / "Edit" → null (not MCP)
60
+ * "mcp__" → null (malformed)
61
+ * "" → null
62
+ *
63
+ * Cursor uses a different prefix (`MCP:<tool>`) with no server segment —
64
+ * the Cursor adapter doesn't call this and the function would always
65
+ * return null on Cursor input by design.
66
+ */
67
+ function extractMcpServerName(toolName) {
68
+ if (typeof toolName !== "string" || !toolName.startsWith("mcp__")) {
69
+ return null;
70
+ }
71
+ const parts = toolName.split("__");
72
+ // Valid shape requires at least 3 segments: "mcp" + server + tool-name
73
+ if (parts.length < 3) {
74
+ return null;
75
+ }
76
+ const server = parts[1];
77
+ return server.length > 0 ? server : null;
78
+ }
79
+ // ─────────────────────────────────────────────────────────────────────────
80
+ // 3. Per-tool tool_input safe-projection (whitelist)
81
+ // ─────────────────────────────────────────────────────────────────────────
82
+ /**
83
+ * Picks a per-tool whitelist of fields out of the raw `tool_input` so the
84
+ * tool_call event carries useful labels for analytics without leaking the
85
+ * sensitive content the agent might include (file contents, full Bash args,
86
+ * env-var dumps, raw API responses, …).
87
+ *
88
+ * Tool list + per-tool key sets come from the authoritative schema doc at
89
+ * `docs/claude-builtin-tool-schemas.md`. The risk model:
90
+ *
91
+ * - keep coarse labels (paths, patterns, mode flags, sub-agent type, model)
92
+ * - drop raw content (file bodies via `Write.content`, edit before/after
93
+ * strings, `NotebookEdit.new_source`, full `Bash.command` text — only
94
+ * the binary name passes through)
95
+ * - keep limited high-risk free-text fields where the value is the most
96
+ * useful analytics signal: `Agent.prompt`, `WebFetch.prompt`,
97
+ * `WebSearch.query`, `AskUserQuestion.questions`, `TodoWrite.todos`,
98
+ * `ExitPlanMode.plan`. These ARE agent-authored free text — collector
99
+ * consumers should be aware.
100
+ *
101
+ * For tools we DON'T have an entry for, the function returns `undefined`
102
+ * to avoid leaking unknown shapes through the wire. Callers that need the
103
+ * raw input (the `bdt_execute` nested-callTool parser, or any
104
+ * browser-devtools MCP tool whose input feeds verify-gate) should bypass
105
+ * this helper for those specific tools.
106
+ */
107
+ /**
108
+ * Extracts the binary / script name from a Bash command, skipping leading
109
+ * env-var assignments (e.g. `KEY=val cmd …` → `cmd`). Returns undefined
110
+ * when the input isn't a string or no candidate token is found.
111
+ */
112
+ function extractCommandBinary(cmd) {
113
+ if (typeof cmd !== "string") {
114
+ return undefined;
115
+ }
116
+ const tokens = cmd.trim().split(/\s+/);
117
+ for (const t of tokens) {
118
+ // skip env-var assignments like FOO=bar / API_KEY=abc
119
+ if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(t)) {
120
+ continue;
121
+ }
122
+ if (t.length > 0) {
123
+ return t;
124
+ }
125
+ }
126
+ return undefined;
127
+ }
128
+ /**
129
+ * Extracts just the slash-command name from a SlashCommand invocation
130
+ * (e.g. `"/commit 'fix: add X'"` → `"/commit"`). Slash-command argument
131
+ * strings can carry user-supplied secrets / project context, so the
132
+ * whitelist drops everything after the first whitespace.
133
+ */
134
+ function extractSlashCommandName(cmd) {
135
+ if (typeof cmd !== "string") {
136
+ return undefined;
137
+ }
138
+ const trimmed = cmd.trim();
139
+ if (trimmed.length === 0) {
140
+ return undefined;
141
+ }
142
+ const firstSpace = trimmed.search(/\s/);
143
+ return firstSpace === -1 ? trimmed : trimmed.slice(0, firstSpace);
144
+ }
145
+ /** Drop keys whose value is `undefined`; preserve `null`, empty strings, 0, false. */
146
+ function compact(o) {
147
+ const out = {};
148
+ for (const k of Object.keys(o)) {
149
+ if (o[k] !== undefined) {
150
+ out[k] = o[k];
151
+ }
152
+ }
153
+ return out;
154
+ }
155
+ function asString(v) {
156
+ return typeof v === "string" ? v : undefined;
157
+ }
158
+ function asNumber(v) {
159
+ return typeof v === "number" ? v : undefined;
160
+ }
161
+ function asBoolean(v) {
162
+ return typeof v === "boolean" ? v : undefined;
163
+ }
164
+ /** Pass-through for arrays; returns undefined for non-array values so the
165
+ * whitelist contract stays "label or absent, never misreport." */
166
+ function asArray(v) {
167
+ return Array.isArray(v) ? v : undefined;
168
+ }
169
+ /**
170
+ * Build the safe `tool_input` projection for a Claude tool invocation.
171
+ *
172
+ * See `docs/claude-builtin-tool-schemas.md` for the source schema for each
173
+ * tool. Returns:
174
+ * - the projected object for any known Claude built-in tool
175
+ * - `undefined` for any MCP / unknown tool (caller handles those flows)
176
+ */
177
+ function extractClaudeToolInput(rawToolName, toolInput) {
178
+ if (typeof toolInput !== "object" || toolInput === null || Array.isArray(toolInput)) {
179
+ return undefined;
180
+ }
181
+ const i = toolInput;
182
+ switch (rawToolName) {
183
+ // ── Shell / process control ──────────────────────────────────────
184
+ case "Bash":
185
+ // schema: { command, description, timeout, run_in_background }
186
+ // Drop raw `command` (env dumps, secrets, full args) — only
187
+ // the binary name passes through.
188
+ return compact({
189
+ command: extractCommandBinary(i.command),
190
+ description: asString(i.description),
191
+ timeout: asNumber(i.timeout),
192
+ run_in_background: asBoolean(i.run_in_background),
193
+ });
194
+ case "BashOutput":
195
+ return compact({
196
+ bash_id: asString(i.bash_id),
197
+ filter: asString(i.filter),
198
+ });
199
+ case "KillShell":
200
+ return compact({ shell_id: asString(i.shell_id) });
201
+ // ── Filesystem ───────────────────────────────────────────────────
202
+ case "Read":
203
+ return compact({
204
+ file_path: asString(i.file_path),
205
+ offset: asNumber(i.offset),
206
+ limit: asNumber(i.limit),
207
+ pages: asString(i.pages),
208
+ });
209
+ case "Write":
210
+ // schema: { file_path, content } — drop `content` (full file body)
211
+ return compact({ file_path: asString(i.file_path) });
212
+ case "Edit":
213
+ // schema: { file_path, old_string, new_string, replace_all } —
214
+ // drop both string fields (raw fragments before/after edit)
215
+ return compact({
216
+ file_path: asString(i.file_path),
217
+ replace_all: asBoolean(i.replace_all),
218
+ });
219
+ case "NotebookEdit":
220
+ // schema includes new_source (cell body) — drop it. Keep
221
+ // structural metadata only.
222
+ return compact({
223
+ notebook_path: asString(i.notebook_path),
224
+ cell_id: asString(i.cell_id),
225
+ cell_type: asString(i.cell_type),
226
+ edit_mode: asString(i.edit_mode),
227
+ });
228
+ // ── Search ───────────────────────────────────────────────────────
229
+ case "Glob":
230
+ return compact({
231
+ pattern: asString(i.pattern),
232
+ path: asString(i.path),
233
+ });
234
+ case "Grep":
235
+ return compact({
236
+ pattern: asString(i.pattern),
237
+ path: asString(i.path),
238
+ glob: asString(i.glob),
239
+ type: asString(i.type),
240
+ output_mode: asString(i.output_mode),
241
+ head_limit: asNumber(i.head_limit),
242
+ multiline: asBoolean(i.multiline),
243
+ "-A": asNumber(i["-A"]),
244
+ "-B": asNumber(i["-B"]),
245
+ "-C": asNumber(i["-C"]),
246
+ "-i": asBoolean(i["-i"]),
247
+ "-n": asBoolean(i["-n"]),
248
+ });
249
+ // ── Web ──────────────────────────────────────────────────────────
250
+ case "WebFetch":
251
+ return compact({
252
+ url: asString(i.url),
253
+ prompt: asString(i.prompt),
254
+ });
255
+ case "WebSearch":
256
+ return compact({
257
+ query: asString(i.query),
258
+ allowed_domains: asArray(i.allowed_domains),
259
+ blocked_domains: asArray(i.blocked_domains),
260
+ });
261
+ // ── Agent / lifecycle ────────────────────────────────────────────
262
+ case "Agent":
263
+ // Legacy alias still emitted in some Claude Code sessions; same shape.
264
+ case "Task":
265
+ // `prompt` and `description` ARE agent-authored free text — kept
266
+ // because they're the most useful sub-agent analytics signal.
267
+ return compact({
268
+ description: asString(i.description),
269
+ prompt: asString(i.prompt),
270
+ subagent_type: asString(i.subagent_type),
271
+ model: asString(i.model),
272
+ isolation: asString(i.isolation),
273
+ run_in_background: asBoolean(i.run_in_background),
274
+ });
275
+ case "TodoWrite":
276
+ // todos[] are agent-authored task strings — useful for
277
+ // "agent's planning trajectory" analytics.
278
+ return compact({ todos: asArray(i.todos) });
279
+ case "ExitPlanMode":
280
+ // `plan` is the agent's full plan text — agent-authored,
281
+ // analytics-relevant. Mirrors the include-the-prompt decision
282
+ // for Agent.prompt.
283
+ return compact({ plan: asString(i.plan) });
284
+ case "AskUserQuestion":
285
+ // Cursor's `AskQuestion` parallel — keep questions verbatim.
286
+ return compact({ questions: asArray(i.questions) });
287
+ // ── Skill / slash invocation ─────────────────────────────────────
288
+ case "Skill":
289
+ // Drop `args` — slash-style argument strings can carry user
290
+ // secrets or project context. Skill name alone is the label.
291
+ return compact({ skill: asString(i.skill) });
292
+ case "SlashCommand":
293
+ // Same rationale as Skill — keep just the command name, drop
294
+ // the argument tail.
295
+ return compact({ command: extractSlashCommandName(i.command) });
296
+ default:
297
+ return undefined;
298
+ }
299
+ }
300
+ const MCP_PREFIX_DOUBLE_UNDERSCORE = "mcp__";
301
+ const SKILL_TOOL_NAME = "Skill";
302
+ /** Claude's agent-spawn tools. "Task" is the legacy alias, still emitted in some sessions. */
303
+ const AGENT_SPAWN_TOOL_NAMES = new Set(["Agent", "Task"]);
304
+ /**
305
+ * Classify a Claude tool invocation. If `tool_input` is malformed or
306
+ * missing the expected discriminator for a typed bucket (`Skill` without
307
+ * `skill`, `Agent` without `subagent_type`), the classifier still assigns
308
+ * the bucket (so downstream can filter on `tool_type`) but falls back to
309
+ * the raw tool name — it never silently drops the bucket tag.
310
+ */
311
+ function classifyTool(rawToolName, toolInput) {
312
+ // MCP: "mcp__<server>__<tool...>"
313
+ if (rawToolName.startsWith(MCP_PREFIX_DOUBLE_UNDERSCORE)) {
314
+ const parts = rawToolName.split("__");
315
+ // ["mcp", server, ...toolSegments]
316
+ if (parts.length >= 3 && parts[1].length > 0) {
317
+ const server = parts[1];
318
+ const bareTool = parts.slice(2).join("__");
319
+ if (bareTool.length > 0) {
320
+ return { tool_type: "mcp", tool_name: bareTool, mcp_server: server };
321
+ }
322
+ }
323
+ // malformed mcp__ prefix — still tag as mcp, keep raw name
324
+ return { tool_type: "mcp", tool_name: rawToolName, mcp_server: null };
325
+ }
326
+ // Skill — canonical discriminator on tool_input.skill
327
+ if (rawToolName === SKILL_TOOL_NAME) {
328
+ const skill = (toolInput && typeof toolInput === "object")
329
+ ? toolInput.skill
330
+ : undefined;
331
+ if (typeof skill === "string" && skill.length > 0) {
332
+ return { tool_type: "skill", tool_name: skill, mcp_server: null };
333
+ }
334
+ // malformed Skill call — tag as skill, fall back to raw name
335
+ return { tool_type: "skill", tool_name: rawToolName, mcp_server: null };
336
+ }
337
+ // Sub-agent spawn — discriminator on tool_input.subagent_type
338
+ if (AGENT_SPAWN_TOOL_NAMES.has(rawToolName)) {
339
+ const subagentType = (toolInput && typeof toolInput === "object")
340
+ ? toolInput.subagent_type
341
+ : undefined;
342
+ if (typeof subagentType === "string" && subagentType.length > 0) {
343
+ return { tool_type: "sub_agent", tool_name: subagentType, mcp_server: null };
344
+ }
345
+ // spawn without explicit subagent_type — defaults to general-purpose at runtime;
346
+ // we keep raw name here so the tag still distinguishes spawn events.
347
+ return { tool_type: "sub_agent", tool_name: rawToolName, mcp_server: null };
348
+ }
349
+ // Native / unknown
350
+ return { tool_type: null, tool_name: rawToolName, mcp_server: null };
351
+ }
352
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/clients/claude/util.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"require-verification.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/require-verification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAuBH,wBAAsB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0F3D"}
1
+ {"version":3,"file":"require-verification.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/require-verification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA2BH,wBAAsB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwG3D"}
@@ -14,12 +14,14 @@
14
14
  */
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.run = run;
17
- const path_1 = require("path");
18
17
  const session_state_1 = require("../../../hooks/core/session-state");
18
+ const actions_1 = require("../../../hooks/core/actions");
19
19
  const activity_1 = require("../../../hooks/core/activity");
20
20
  const config_1 = require("../../../lib/config");
21
21
  const logger_1 = require("../../../lib/logger");
22
22
  const stdin_1 = require("../../../lib/stdin");
23
+ /** MCP server key that this hook is routed to via the `MCP:bdt_.*` matcher. */
24
+ const MCP_SERVER_NAME = "browser-devtools";
23
25
  async function run(projectDir) {
24
26
  let input;
25
27
  try {
@@ -73,7 +75,7 @@ Then use other browser tools to verify your changes.`,
73
75
  const traceId = (0, session_state_1.getActiveTraceId)(sessionDir);
74
76
  const activityId = (0, session_state_1.getActiveActivityId)(sessionDir);
75
77
  // inject _metadata into tool input so MCP server knows session/trace context
76
- const projectName = (0, path_1.basename)(projectDir);
78
+ const projectName = (0, actions_1.resolveProjectName)(projectDir);
77
79
  const traceStateParts = [`prj:${projectName}`, `sid:${sessionId}`];
78
80
  if (activityId) {
79
81
  traceStateParts.push(`aid:${activityId}`);
@@ -90,6 +92,20 @@ Then use other browser tools to verify your changes.`,
90
92
  traceId,
91
93
  traceState,
92
94
  };
95
+ if (input.tool_use_id) {
96
+ metadata.toolUseId = input.tool_use_id;
97
+ }
98
+ // Cursor's postToolUse stdin doesn't expose the MCP server and its
99
+ // tool_name format (`MCP:bdt_*`) has no server segment. But the
100
+ // matcher restricts this hook to `MCP:bdt_.*` — i.e. we KNOW it's the
101
+ // browser-devtools MCP server by virtue of routing. Hardcode the name
102
+ // so MCP-emitted telemetry carries the same `mcp_server` dimension as
103
+ // on the Claude adapter.
104
+ metadata.mcpServer = MCP_SERVER_NAME;
105
+ const userEmail = (0, session_state_1.getUserEmail)(sessionDir);
106
+ if (userEmail) {
107
+ metadata.userEmail = userEmail;
108
+ }
93
109
  if (config.collector?.url) {
94
110
  metadata.collectorUrl = config.collector.url;
95
111
  }
@@ -1 +1 @@
1
- {"version":3,"file":"require-verification.js","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/require-verification.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"require-verification.js","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/require-verification.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"session-end.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/session-end.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAYH,wBAAsB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8B3D"}
1
+ {"version":3,"file":"session-end.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/session-end.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,wBAAsB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkC3D"}
@@ -13,6 +13,7 @@ const actions_1 = require("../../../hooks/core/actions");
13
13
  const activity_1 = require("../../../hooks/core/activity");
14
14
  const logger_1 = require("../../../lib/logger");
15
15
  const stdin_1 = require("../../../lib/stdin");
16
+ const queue_1 = require("../../../queue");
16
17
  async function run(projectDir) {
17
18
  let input;
18
19
  try {
@@ -38,6 +39,9 @@ async function run(projectDir) {
38
39
  reason: input.reason,
39
40
  };
40
41
  await (0, actions_1.appendAction)(actionsFile, entry);
42
+ // Final-flush the queue synchronously — consumer is about to exit; this
43
+ // is the last reliable chance to drain. §5.6 docs/job-queue.md.
44
+ await (0, queue_1.flushSynchronously)(projectDir, sessionId);
41
45
  logger_1.logger.debug(`session-end: ${sessionId}`);
42
46
  process.exit(0);
43
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"session-end.js","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/session-end.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAYH,kBA8BC;AAxCD,yDAAsH;AACtH,2DAA2D;AAC3D,gDAAyD;AACzD,8CAA+C;AAOxC,KAAK,UAAU,GAAG,CAAC,UAAkB;IACxC,IAAI,KAA4B,CAAC;IACjC,IAAI,CAAC;QACD,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAS,GAAE,CAA0B,CAAC;IAC7D,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QAClB,eAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,SAAS,GAAW,KAAK,CAAC,eAAe,IAAI,SAAS,CAAC;IAC7D,MAAM,UAAU,GAAW,GAAG,UAAU,sBAAsB,SAAS,EAAE,CAAC;IAC1E,MAAM,WAAW,GAAW,GAAG,UAAU,gBAAgB,CAAC;IAC1D,IAAA,mBAAU,EAAC,GAAG,UAAU,cAAc,CAAC,CAAC;IAExC,0BAA0B;IAC1B,MAAM,IAAA,sBAAW,EAAC,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC;IAE/C,MAAM,GAAG,GAAW,IAAI,CAAC,GAAG,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAqB;QAC5B,GAAG,IAAA,oBAAU,EAAC,WAAW,CAAC;QAC1B,IAAI,EAAE,aAAa;QACnB,SAAS,EAAE,GAAG;QACd,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,IAAA,qCAA2B,EAAC,WAAW,EAAE,eAAe,EAAE,GAAG,CAAC;QACxE,MAAM,EAAE,KAAK,CAAC,MAAM;KACvB,CAAC;IACF,MAAM,IAAA,sBAAY,EAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAEvC,eAAM,CAAC,KAAK,CAAC,gBAAgB,SAAS,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"session-end.js","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/session-end.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAaH,kBAkCC;AA7CD,yDAAsH;AACtH,2DAA2D;AAC3D,gDAAyD;AACzD,8CAA+C;AAC/C,0CAAoD;AAO7C,KAAK,UAAU,GAAG,CAAC,UAAkB;IACxC,IAAI,KAA4B,CAAC;IACjC,IAAI,CAAC;QACD,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAS,GAAE,CAA0B,CAAC;IAC7D,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QAClB,eAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,SAAS,GAAW,KAAK,CAAC,eAAe,IAAI,SAAS,CAAC;IAC7D,MAAM,UAAU,GAAW,GAAG,UAAU,sBAAsB,SAAS,EAAE,CAAC;IAC1E,MAAM,WAAW,GAAW,GAAG,UAAU,gBAAgB,CAAC;IAC1D,IAAA,mBAAU,EAAC,GAAG,UAAU,cAAc,CAAC,CAAC;IAExC,0BAA0B;IAC1B,MAAM,IAAA,sBAAW,EAAC,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC;IAE/C,MAAM,GAAG,GAAW,IAAI,CAAC,GAAG,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAqB;QAC5B,GAAG,IAAA,oBAAU,EAAC,WAAW,CAAC;QAC1B,IAAI,EAAE,aAAa;QACnB,SAAS,EAAE,GAAG;QACd,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,IAAA,qCAA2B,EAAC,WAAW,EAAE,eAAe,EAAE,GAAG,CAAC;QACxE,MAAM,EAAE,KAAK,CAAC,MAAM;KACvB,CAAC;IACF,MAAM,IAAA,sBAAY,EAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAEvC,wEAAwE;IACxE,gEAAgE;IAChE,MAAM,IAAA,0BAAkB,EAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAEhD,eAAM,CAAC,KAAK,CAAC,gBAAgB,SAAS,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"session-start.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/session-start.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmBH,wBAAsB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqE3D"}
1
+ {"version":3,"file":"session-start.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/session-start.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH,wBAAsB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyE3D"}
@@ -27,6 +27,10 @@ async function run(projectDir) {
27
27
  const sessionId = input.conversation_id ?? "default";
28
28
  const actionsFile = `${projectDir}/.ironbee/sessions/${sessionId}/actions.jsonl`;
29
29
  (0, logger_1.setLogFile)(`${projectDir}/.ironbee/sessions/${sessionId}/session.log`);
30
+ const sessionDir = `${projectDir}/.ironbee/sessions/${sessionId}`;
31
+ // Cursor provides user_email on every hook stdin — cache the first read
32
+ // in state.json so non-stdin callers (spawned workers, analyze) get it.
33
+ (0, session_state_1.setUserEmail)(sessionDir, input.user_email ?? undefined);
30
34
  const entry = {
31
35
  ...(0, actions_1.baseFields)(actionsFile),
32
36
  type: "session_start",
@@ -35,7 +39,6 @@ async function run(projectDir) {
35
39
  client: "cursor",
36
40
  source: "startup",
37
41
  };
38
- const sessionDir = `${projectDir}/.ironbee/sessions/${sessionId}`;
39
42
  await (0, actions_1.appendAction)(actionsFile, entry);
40
43
  await (0, session_state_1.reconcileSessionState)(sessionDir, actionsFile, actions_1.appendAction);
41
44
  await (0, telemetry_1.trackSessionStart)("cursor", sessionId);
@@ -1 +1 @@
1
- {"version":3,"file":"session-start.js","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/session-start.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAmBH,kBAqEC;AAtFD,yDAA2F;AAC3F,qEAA0E;AAC1E,gDAAyD;AACzD,gDAAmD;AACnD,8CAA+C;AAC/C,sDAA2D;AAYpD,KAAK,UAAU,GAAG,CAAC,UAAkB;IACxC,IAAI,KAA8B,CAAC;IACnC,IAAI,CAAC;QACD,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAS,GAAE,CAA4B,CAAC;IAC/D,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QAClB,eAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAA,qBAAY,EAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACpC,OAAO;IACX,CAAC;IAED,MAAM,SAAS,GAAW,KAAK,CAAC,eAAe,IAAI,SAAS,CAAC;IAC7D,MAAM,WAAW,GAAW,GAAG,UAAU,sBAAsB,SAAS,gBAAgB,CAAC;IACzF,IAAA,mBAAU,EAAC,GAAG,UAAU,sBAAsB,SAAS,cAAc,CAAC,CAAC;IAEvE,MAAM,KAAK,GAAuB;QAC9B,GAAG,IAAA,oBAAU,EAAC,WAAW,CAAC;QAC1B,IAAI,EAAE,eAAe;QACrB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,UAAU,EAAE,SAAS;QACrB,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,SAAS;KACpB,CAAC;IAEF,MAAM,UAAU,GAAW,GAAG,UAAU,sBAAsB,SAAS,EAAE,CAAC;IAC1E,MAAM,IAAA,sBAAY,EAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACvC,MAAM,IAAA,qCAAqB,EAAC,UAAU,EAAE,WAAW,EAAE,sBAAY,CAAC,CAAC;IACnE,MAAM,IAAA,6BAAiB,EAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC7C,eAAM,CAAC,KAAK,CAAC,kBAAkB,SAAS,EAAE,CAAC,CAAC;IAE5C,MAAM,WAAW,GAAW,IAAI,CAAC,SAAS,CAAC;QACvC,UAAU,EAAE,SAAS;QACrB,MAAM,EAAE,MAAM;QACd,YAAY,EAAE,CAAC,qCAAqC,CAAC;QACrD,MAAM,EAAE,CAAC,2BAA2B,EAAE,0BAA0B,CAAC;QACjE,cAAc,EAAE,CAAC;QACjB,gBAAgB,EAAE,CAAC;KACtB,CAAC,CAAC;IACH,MAAM,WAAW,GAAW,IAAI,CAAC,SAAS,CAAC;QACvC,UAAU,EAAE,SAAS;QACrB,MAAM,EAAE,MAAM;QACd,YAAY,EAAE,CAAC,qCAAqC,CAAC;QACrD,MAAM,EAAE,CAAC,cAAc,EAAE,4BAA4B,CAAC;QACtD,cAAc,EAAE,CAAC;QACjB,gBAAgB,EAAE,CAAC;QACnB,MAAM,EAAE,CAAC,iCAAiC,EAAE,sBAAsB,CAAC;KACtE,CAAC,CAAC;IAEH,MAAM,OAAO,GAAW;cACd,SAAS;;;;;;;;UAQb,WAAW;;;UAGX,WAAW;;;;2FAIsE,CAAC;IAExF,MAAM,MAAM,GAA6B;QACrC,kBAAkB,EAAE,OAAO;KAC9B,CAAC;IACF,IAAA,qBAAY,EAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5C,CAAC"}
1
+ {"version":3,"file":"session-start.js","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/session-start.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAsBH,kBAyEC;AA7FD,yDAA2F;AAC3F,qEAAwF;AACxF,gDAAyD;AACzD,gDAAmD;AACnD,8CAA+C;AAC/C,sDAA2D;AAepD,KAAK,UAAU,GAAG,CAAC,UAAkB;IACxC,IAAI,KAA8B,CAAC;IACnC,IAAI,CAAC;QACD,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAS,GAAE,CAA4B,CAAC;IAC/D,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QAClB,eAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;QAC5C,IAAA,qBAAY,EAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACpC,OAAO;IACX,CAAC;IAED,MAAM,SAAS,GAAW,KAAK,CAAC,eAAe,IAAI,SAAS,CAAC;IAC7D,MAAM,WAAW,GAAW,GAAG,UAAU,sBAAsB,SAAS,gBAAgB,CAAC;IACzF,IAAA,mBAAU,EAAC,GAAG,UAAU,sBAAsB,SAAS,cAAc,CAAC,CAAC;IAEvE,MAAM,UAAU,GAAW,GAAG,UAAU,sBAAsB,SAAS,EAAE,CAAC;IAC1E,wEAAwE;IACxE,wEAAwE;IACxE,IAAA,4BAAY,EAAC,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,SAAS,CAAC,CAAC;IAExD,MAAM,KAAK,GAAuB;QAC9B,GAAG,IAAA,oBAAU,EAAC,WAAW,CAAC;QAC1B,IAAI,EAAE,eAAe;QACrB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,UAAU,EAAE,SAAS;QACrB,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,SAAS;KACpB,CAAC;IAEF,MAAM,IAAA,sBAAY,EAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACvC,MAAM,IAAA,qCAAqB,EAAC,UAAU,EAAE,WAAW,EAAE,sBAAY,CAAC,CAAC;IACnE,MAAM,IAAA,6BAAiB,EAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC7C,eAAM,CAAC,KAAK,CAAC,kBAAkB,SAAS,EAAE,CAAC,CAAC;IAE5C,MAAM,WAAW,GAAW,IAAI,CAAC,SAAS,CAAC;QACvC,UAAU,EAAE,SAAS;QACrB,MAAM,EAAE,MAAM;QACd,YAAY,EAAE,CAAC,qCAAqC,CAAC;QACrD,MAAM,EAAE,CAAC,2BAA2B,EAAE,0BAA0B,CAAC;QACjE,cAAc,EAAE,CAAC;QACjB,gBAAgB,EAAE,CAAC;KACtB,CAAC,CAAC;IACH,MAAM,WAAW,GAAW,IAAI,CAAC,SAAS,CAAC;QACvC,UAAU,EAAE,SAAS;QACrB,MAAM,EAAE,MAAM;QACd,YAAY,EAAE,CAAC,qCAAqC,CAAC;QACrD,MAAM,EAAE,CAAC,cAAc,EAAE,4BAA4B,CAAC;QACtD,cAAc,EAAE,CAAC;QACjB,gBAAgB,EAAE,CAAC;QACnB,MAAM,EAAE,CAAC,iCAAiC,EAAE,sBAAsB,CAAC;KACtE,CAAC,CAAC;IAEH,MAAM,OAAO,GAAW;cACd,SAAS;;;;;;;;UAQb,WAAW;;;UAGX,WAAW;;;;2FAIsE,CAAC;IAExF,MAAM,MAAM,GAA6B;QACrC,kBAAkB,EAAE,OAAO;KAC9B,CAAC;IACF,IAAA,qBAAY,EAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5C,CAAC"}
@@ -1,16 +1,38 @@
1
1
  /**
2
2
  * Cursor — track-action hook adapter
3
3
  *
4
- * postToolUse hook for browser-devtools MCP tool calls.
5
- * Filtered by matcher in hooks.json so only browser-devtools
6
- * tools trigger this hook no script-level filtering needed.
4
+ * Runs on both `postToolUse` (success) and `postToolUseFailure` (error).
5
+ * Cursor has no matcher support for postToolUseFailure, so every tool fires
6
+ * the hook. Failure is detected via `error_message` on stdin, and Cursor
7
+ * provides richer failure metadata (`failure_type`, `is_interrupt`,
8
+ * `duration`) that we fold into the event.
7
9
  *
8
- * Cursor's postToolUse uses `MCP:<tool_name>` format for tool_name.
9
- * We normalize to `mcp__browser-devtools__<tool_name>` so that
10
- * core verify-gate logic can match them consistently.
10
+ * Responsibilities:
11
+ * 1. **browser-devtools tools** (`MCP:bdt_*`): classify via the shared
12
+ * taxonomy so tool_type/tool_name/mcp_server match Claude's schema,
13
+ * append the tool_call entry to `actions.jsonl` (verify-gate source
14
+ * of truth), update recording state, and extract nested `callTool()`
15
+ * from bdt_execute. Queue submit is SKIPPED: browser-devtools-mcp
16
+ * ships these directly to the collector already. tool_input is kept
17
+ * AS-IS for these so the local nested parser keeps working.
18
+ * 2. **All other tools** (Shell / Read / Write / Grep / Delete / Task /
19
+ * non-browser MCP): submit a send_event job. `tool_input` is replaced
20
+ * with a per-tool safe projection (see `extractCursorToolInput`) —
21
+ * only labels (`file_path`, `pattern`, `working_directory`,
22
+ * `subagent_type`, …) survive, never raw content. `tool_output` stays
23
+ * stripped from the wire (its content is high-risk and undocumented).
24
+ * `tool_input_size` and `tool_response_size` reflect the ORIGINAL raw
25
+ * byte counts.
11
26
  *
12
- * Handles both direct tool calls and nested callTool() invocations
13
- * inside the execute tool.
27
+ * MCP server note: Cursor's wire format (`MCP:<tool>`) does not carry the
28
+ * server name, so the classifier returns `mcp_server: null`. For bdt_*
29
+ * tools we override with `browser-devtools` locally — the matcher routing
30
+ * + tool prefix are enough to identify the server. For other MCP tools we
31
+ * leave it null (unknown).
32
+ *
33
+ * On failure: the event's `error` field is populated (with `failure_type:`
34
+ * prefix + interrupt marker when applicable) and the response is omitted.
35
+ * Cursor's own `duration` overrides the null placeholder when present.
14
36
  */
15
37
  export declare function run(projectDir: string): Promise<void>;
16
38
  //# sourceMappingURL=track-action.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"track-action.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/track-action.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAuGH,wBAAsB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmF3D"}
1
+ {"version":3,"file":"track-action.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/track-action.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAgHH,wBAAsB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8I3D"}