@mnemonik/cursor-hooks 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/hook.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/hook.js ADDED
@@ -0,0 +1,456 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync } from 'node:fs';
3
+ import { relative, resolve } from 'node:path';
4
+ import { exit, stderr, stdin, stdout } from 'node:process';
5
+ import { PRE_BASH_GATE, PRE_EDIT_GATE, PRE_MCP_GATE, PROMPT_CONTEXT, CHECKPOINT_PRESSURE, PRECOMPACT_OBSERVE, SUBAGENT_TRACK, } from './lib/behavior.js';
6
+ import { additionalContext, ask, continueWith, deny, stopWithFollowup, trimContext, } from './lib/cursorOutput.js';
7
+ import { isNonInteractive, parseBypass, resolveConfig } from './lib/env.js';
8
+ import { fetchHookContext, fetchMcpPrecheck, fetchPolicyReminder, fetchSnapshot, reportBypass, reportGateFired, reportSubagent, trackIdeEdit, } from './lib/http.js';
9
+ import { matchIrreducibleDeny } from './lib/shellTokens.js';
10
+ const MNEMONIK_MCP_PREFIX = /^(mnemonik\.|MCP:mnemonik\.)/;
11
+ async function readStdin() {
12
+ return new Promise((res) => {
13
+ let buf = '';
14
+ let settled = false;
15
+ const finish = (value) => {
16
+ if (settled)
17
+ return;
18
+ settled = true;
19
+ res(value);
20
+ };
21
+ stdin.setEncoding('utf8');
22
+ stdin.on('data', (chunk) => {
23
+ buf += chunk;
24
+ if (buf.length > 1_048_576)
25
+ finish(null);
26
+ });
27
+ stdin.on('end', () => {
28
+ try {
29
+ finish(JSON.parse(buf));
30
+ }
31
+ catch {
32
+ finish(null);
33
+ }
34
+ });
35
+ stdin.on('error', () => finish(null));
36
+ });
37
+ }
38
+ function writeOutput(output) {
39
+ if (output)
40
+ stdout.write(JSON.stringify(output));
41
+ exit(0);
42
+ }
43
+ function writeAllow() {
44
+ exit(0);
45
+ }
46
+ function warnAndAllow(message) {
47
+ stderr.write(`mnemonik-cursor-hook: ${message}\n`);
48
+ exit(0);
49
+ }
50
+ function sessionId(input) {
51
+ return input.conversation_id ?? input.generation_id ?? 'cursor-unknown-session';
52
+ }
53
+ function cwdOf(input) {
54
+ return input.cwd ?? input.workspace_roots?.[0] ?? process.cwd();
55
+ }
56
+ async function emitGateFired(input, config, tool, mode, outcome) {
57
+ await reportGateFired({
58
+ server: config.server,
59
+ apiKey: config.apiKey,
60
+ cwd: cwdOf(input),
61
+ cursorSessionId: sessionId(input),
62
+ tool,
63
+ mode,
64
+ outcome,
65
+ });
66
+ }
67
+ function fileTargetsFromToolInput(toolName, toolInput, cwd) {
68
+ if (!toolInput)
69
+ return [];
70
+ const candidates = [];
71
+ const path = toolInput.path ?? toolInput.file_path ?? toolInput.filePath;
72
+ if (typeof path === 'string' && path.trim())
73
+ candidates.push(path);
74
+ // Cursor's Write tool may also describe multiple files via an array.
75
+ const paths = toolInput.paths ?? toolInput.file_paths ?? toolInput.filePaths;
76
+ if (Array.isArray(paths)) {
77
+ for (const p of paths)
78
+ if (typeof p === 'string' && p.trim())
79
+ candidates.push(p);
80
+ }
81
+ return candidates.map((p) => (p.startsWith('/') ? p : resolve(cwd, p)));
82
+ }
83
+ function covered(snapshot, cwd, absolutePath) {
84
+ const rel = relative(cwd, absolutePath);
85
+ return snapshot.coveredFiles.includes(absolutePath) || snapshot.coveredFiles.includes(rel);
86
+ }
87
+ async function getSnapshotOrFailOpen(input, config, tool, mode) {
88
+ if (!config.apiKey) {
89
+ warnAndAllow('MNEMONIK_API_KEY missing - fail-open. Run mnemonik-cursor-hooks install.');
90
+ }
91
+ const snapshot = await fetchSnapshot({
92
+ server: config.server,
93
+ apiKey: config.apiKey,
94
+ cwd: cwdOf(input),
95
+ cursorSessionId: sessionId(input),
96
+ });
97
+ if (!snapshot) {
98
+ await emitGateFired(input, config, tool, mode, 'unreachable');
99
+ warnAndAllow('mnemonik server unreachable - fail-open.');
100
+ }
101
+ if (!snapshot.ok && snapshot.reason !== 'no_active_session') {
102
+ await emitGateFired(input, config, tool, mode, snapshot.reason ?? 'snapshot_not_ok');
103
+ writeAllow();
104
+ }
105
+ return snapshot;
106
+ }
107
+ async function handleSessionStart(input, config) {
108
+ if (PROMPT_CONTEXT === 'off')
109
+ writeAllow();
110
+ if (!config.apiKey)
111
+ writeAllow();
112
+ const ctx = await fetchHookContext({
113
+ server: config.server,
114
+ apiKey: config.apiKey,
115
+ cwd: cwdOf(input),
116
+ cursorSessionId: sessionId(input),
117
+ event: 'SessionStart',
118
+ });
119
+ if (!ctx?.ok || !ctx.additionalContext)
120
+ writeAllow();
121
+ writeOutput(additionalContext(trimContext(ctx.additionalContext)));
122
+ }
123
+ async function handleBeforeSubmitPrompt(input, config) {
124
+ if (PROMPT_CONTEXT === 'off')
125
+ writeAllow();
126
+ const usage = typeof input.context_usage_percent === 'number' ? input.context_usage_percent : 0;
127
+ if (usage <= 85) {
128
+ writeOutput(continueWith());
129
+ }
130
+ if (!config.apiKey) {
131
+ writeOutput(continueWith());
132
+ }
133
+ const ctx = await fetchHookContext({
134
+ server: config.server,
135
+ apiKey: config.apiKey,
136
+ cwd: cwdOf(input),
137
+ cursorSessionId: sessionId(input),
138
+ event: 'BeforeSubmitPrompt',
139
+ prompt: input.prompt,
140
+ });
141
+ if (!ctx?.ok || !ctx.systemMessage) {
142
+ writeOutput(continueWith('Mnemonik: approaching context limit — consider calling mnemonik.checkpoint before continuing.'));
143
+ }
144
+ writeOutput(continueWith(trimContext(ctx.systemMessage, 4_000)));
145
+ }
146
+ async function handlePreToolUse(input, config) {
147
+ const mode = PRE_EDIT_GATE;
148
+ const tool = input.tool_name ?? 'Write';
149
+ if (mode === 'off') {
150
+ await emitGateFired(input, config, tool, 'off', 'off');
151
+ writeAllow();
152
+ }
153
+ const cwd = cwdOf(input);
154
+ const targets = fileTargetsFromToolInput(tool, input.tool_input, cwd);
155
+ const existingTargets = targets.filter((path) => existsSync(path));
156
+ if (existingTargets.length === 0) {
157
+ await emitGateFired(input, config, tool, mode, 'new_or_no_file');
158
+ writeAllow();
159
+ }
160
+ const snapshot = await getSnapshotOrFailOpen(input, config, tool, mode);
161
+ if (!snapshot)
162
+ writeAllow();
163
+ const uncovered = existingTargets.filter((path) => !covered(snapshot, cwd, path));
164
+ if (uncovered.length === 0) {
165
+ await emitGateFired(input, config, tool, mode, 'covered');
166
+ writeAllow();
167
+ }
168
+ const files = uncovered.map((p) => relative(cwd, p));
169
+ if (mode === 'advisory') {
170
+ await emitGateFired(input, config, tool, mode, 'nudge');
171
+ // Cursor preToolUse cannot inject additional_context (per docs); use user_message for the nudge.
172
+ writeOutput({
173
+ permission: 'allow',
174
+ user_message: [
175
+ `Mnemonik: file_context has not been called for ${files.map((f) => `"${f}"`).join(', ')} in this session.`,
176
+ 'Recommended: call mnemonik.file_context({ filePaths: [...] }) before editing existing files.',
177
+ ].join(' '),
178
+ });
179
+ }
180
+ await emitGateFired(input, config, tool, mode, 'deny');
181
+ writeOutput(deny([
182
+ 'MNEMONIK_FILE_CONTEXT_REQUIRED',
183
+ `Edit blocked: file_context has not been called for ${files.map((f) => `"${f}"`).join(', ')} in this session.`,
184
+ 'Fix: call mnemonik.file_context({ filePaths: [...] }) first.',
185
+ 'Bypass: MNEMONIK_BYPASS_HOOKS=1 MNEMONIK_BYPASS_TYPE=<typo|formatting|regenerated|already_grounded|other>.',
186
+ ].join('\n')));
187
+ }
188
+ async function handlePostToolUse(input, config) {
189
+ const tool = input.tool_name ?? '';
190
+ const cwd = cwdOf(input);
191
+ const targets = fileTargetsFromToolInput(tool, input.tool_input, cwd);
192
+ for (const target of targets) {
193
+ await trackIdeEdit({
194
+ server: config.server,
195
+ apiKey: config.apiKey,
196
+ sessionId: sessionId(input),
197
+ filePath: target,
198
+ });
199
+ }
200
+ if (!config.apiKey)
201
+ writeAllow();
202
+ const ctx = await fetchHookContext({
203
+ server: config.server,
204
+ apiKey: config.apiKey,
205
+ cwd,
206
+ cursorSessionId: sessionId(input),
207
+ event: 'PostToolUse',
208
+ toolName: tool,
209
+ filePaths: targets,
210
+ });
211
+ if (!ctx?.ok || !ctx.additionalContext)
212
+ writeAllow();
213
+ writeOutput(additionalContext(trimContext(ctx.additionalContext, 8_000)));
214
+ }
215
+ async function handleBeforeShellExecution(input, config) {
216
+ if (PRE_BASH_GATE === 'off')
217
+ writeAllow();
218
+ const command = (input.command ?? '').toString();
219
+ if (!command.trim())
220
+ writeAllow();
221
+ // Layer 1: irreducible deny-floor.
222
+ const denyName = matchIrreducibleDeny(command);
223
+ if (denyName) {
224
+ await emitGateFired(input, config, 'Shell', 'enforce', `irreducible_deny_${denyName}`);
225
+ writeOutput(deny([
226
+ 'MNEMONIK_IRREDUCIBLE_DENY',
227
+ `Shell blocked: command matches the catastrophic-action floor (${denyName}).`,
228
+ 'These three patterns (rm -rf / | ~ | $HOME, dd of=<whole-disk>, mkfs <whole-disk>) are blocked unconditionally because the cost of a false negative is "your machine."',
229
+ 'Bypass for legitimate one-off use: MNEMONIK_BYPASS_HOOKS=1 + MNEMONIK_BYPASS_TYPE=other + MNEMONIK_BYPASS_DETAIL 50-200 chars.',
230
+ ].join('\n')));
231
+ }
232
+ // Layer 2: server-side policy reminder.
233
+ if (!config.apiKey) {
234
+ await emitGateFired(input, config, 'Shell', 'advisory', 'no_api_key');
235
+ writeAllow();
236
+ }
237
+ const reminder = await fetchPolicyReminder({
238
+ server: config.server,
239
+ apiKey: config.apiKey,
240
+ cwd: cwdOf(input),
241
+ cursorSessionId: sessionId(input),
242
+ tool: 'Shell',
243
+ context: command,
244
+ });
245
+ if (!reminder?.ok || reminder.policies.length === 0) {
246
+ await emitGateFired(input, config, 'Shell', 'advisory', reminder ? 'no_match' : 'unreachable');
247
+ writeAllow();
248
+ }
249
+ const actionClass = reminder.policies.filter((p) => p.kind === 'mustConfirm' || p.kind === 'forbiddenCommand');
250
+ if (actionClass.length === 0) {
251
+ await emitGateFired(input, config, 'Shell', 'advisory', 'default_mode_only');
252
+ writeAllow();
253
+ }
254
+ const lines = [
255
+ 'Mnemonik: project policies matched this command. Read each rule and act accordingly.',
256
+ ];
257
+ for (const p of actionClass) {
258
+ const desc = p.description ?? p.pattern;
259
+ const repl = p.replacement ? ` Replacement: ${p.replacement}.` : '';
260
+ lines.push(`- [${p.kind}] ${desc}${repl}`);
261
+ }
262
+ await emitGateFired(input, config, 'Shell', 'advisory', `policy_match_${actionClass.length}`);
263
+ // Cursor supports `ask` on beforeShellExecution; use it for mustConfirm/forbidden matches.
264
+ writeOutput(ask(lines.join('\n'), lines.join('\n')));
265
+ }
266
+ async function handleBeforeMCPExecution(input, config) {
267
+ if (PRE_MCP_GATE === 'off')
268
+ writeAllow();
269
+ const tool = input.mcp_tool ?? input.tool_name ?? '';
270
+ if (!MNEMONIK_MCP_PREFIX.test(tool))
271
+ writeAllow();
272
+ if (!config.apiKey) {
273
+ await emitGateFired(input, config, tool, 'advisory', 'no_api_key');
274
+ writeAllow();
275
+ }
276
+ const args = (input.mcp_args ?? input.tool_input ?? {});
277
+ const result = await fetchMcpPrecheck({
278
+ server: config.server,
279
+ apiKey: config.apiKey,
280
+ cwd: cwdOf(input),
281
+ cursorSessionId: sessionId(input),
282
+ tool,
283
+ args,
284
+ model: input.model,
285
+ });
286
+ if (!result?.ok) {
287
+ await emitGateFired(input, config, tool, 'advisory', result ? 'not_ok' : 'unreachable');
288
+ writeAllow();
289
+ }
290
+ if (result.verdict === 'allow') {
291
+ await emitGateFired(input, config, tool, 'advisory', 'allow');
292
+ writeAllow();
293
+ }
294
+ if (result.verdict === 'deny') {
295
+ await emitGateFired(input, config, tool, 'advisory', 'deny');
296
+ writeOutput(deny(result.agent_message ?? 'Mnemonik: precheck denied.', result.reason ?? undefined));
297
+ }
298
+ // verdict === 'ask'
299
+ await emitGateFired(input, config, tool, 'advisory', 'ask');
300
+ writeOutput(ask(result.agent_message ?? 'Mnemonik: precheck requests confirmation.', result.reason ?? undefined));
301
+ }
302
+ async function handleAfterMCPExecution(input, config) {
303
+ const tool = input.mcp_tool ?? input.tool_name ?? '';
304
+ if (!MNEMONIK_MCP_PREFIX.test(tool))
305
+ writeAllow();
306
+ // Fire-and-forget telemetry: which Mnemonik tools fire how often, observed outcomes.
307
+ await emitGateFired(input, config, tool, 'advisory', 'mcp_executed');
308
+ writeAllow();
309
+ }
310
+ async function handleAfterFileEdit(input, config) {
311
+ const filePath = input.file_path;
312
+ if (!filePath)
313
+ writeAllow();
314
+ await trackIdeEdit({
315
+ server: config.server,
316
+ apiKey: config.apiKey,
317
+ sessionId: sessionId(input),
318
+ filePath,
319
+ });
320
+ writeAllow();
321
+ }
322
+ async function handleStop(input, config) {
323
+ if (CHECKPOINT_PRESSURE === 'off')
324
+ writeAllow();
325
+ if (!config.apiKey)
326
+ writeAllow();
327
+ const ctx = await fetchHookContext({
328
+ server: config.server,
329
+ apiKey: config.apiKey,
330
+ cwd: cwdOf(input),
331
+ cursorSessionId: sessionId(input),
332
+ event: 'Stop',
333
+ });
334
+ if (!ctx?.ok || !ctx.continuationReason)
335
+ writeAllow();
336
+ writeOutput(stopWithFollowup(trimContext(ctx.continuationReason, 4_000)));
337
+ }
338
+ async function handleSubagentLifecycle(input, config, event) {
339
+ if (SUBAGENT_TRACK === 'off')
340
+ writeAllow();
341
+ if (!input.subagent_id)
342
+ writeAllow();
343
+ await reportSubagent({
344
+ server: config.server,
345
+ apiKey: config.apiKey,
346
+ cwd: cwdOf(input),
347
+ cursorSessionId: sessionId(input),
348
+ event,
349
+ subagentId: input.subagent_id,
350
+ subagentType: input.subagent_type,
351
+ task: input.task,
352
+ parentConversationId: input.parent_conversation_id,
353
+ toolCallId: input.tool_call_id,
354
+ subagentModel: input.subagent_model,
355
+ isParallelWorker: input.is_parallel_worker,
356
+ gitBranch: input.git_branch,
357
+ status: input.status,
358
+ durationMs: input.duration_ms,
359
+ });
360
+ if (event === 'stop' && CHECKPOINT_PRESSURE === 'advisory' && config.apiKey) {
361
+ const ctx = await fetchHookContext({
362
+ server: config.server,
363
+ apiKey: config.apiKey,
364
+ cwd: cwdOf(input),
365
+ cursorSessionId: sessionId(input),
366
+ event: 'SubagentStop',
367
+ });
368
+ if (ctx?.ok && ctx.continuationReason) {
369
+ writeOutput(stopWithFollowup(trimContext(ctx.continuationReason, 4_000)));
370
+ }
371
+ }
372
+ writeAllow();
373
+ }
374
+ async function handlePreCompact(input, config) {
375
+ if (PRECOMPACT_OBSERVE === 'off')
376
+ writeAllow();
377
+ const usage = typeof input.context_usage_percent === 'number' ? Math.round(input.context_usage_percent) : -1;
378
+ const msgs = typeof input.messages_to_compact === 'number' ? input.messages_to_compact : -1;
379
+ const first = input.is_first_compaction ? 'first' : 'subsequent';
380
+ await emitGateFired(input, config, 'preCompact', 'advisory', `compact_${first}_u${usage}_m${msgs}`);
381
+ writeAllow();
382
+ }
383
+ async function dispatch(input) {
384
+ if (isNonInteractive())
385
+ writeAllow();
386
+ const bypass = parseBypass();
387
+ if (bypass.invalidReason) {
388
+ stderr.write(`mnemonik-cursor-hook: invalid bypass envelope - ${bypass.invalidReason}\n`);
389
+ }
390
+ const config = await resolveConfig(cwdOf(input));
391
+ if (bypass.active) {
392
+ await reportBypass({
393
+ server: config.server,
394
+ apiKey: config.apiKey,
395
+ cwd: cwdOf(input),
396
+ cursorSessionId: sessionId(input),
397
+ tool: input.tool_name ?? input.mcp_tool ?? input.hook_event_name,
398
+ bypassType: bypass.type ?? 'unknown',
399
+ detail: bypass.detail,
400
+ });
401
+ writeAllow();
402
+ }
403
+ switch (input.hook_event_name) {
404
+ case 'sessionStart':
405
+ await handleSessionStart(input, config);
406
+ break;
407
+ case 'beforeSubmitPrompt':
408
+ await handleBeforeSubmitPrompt(input, config);
409
+ break;
410
+ case 'preToolUse':
411
+ await handlePreToolUse(input, config);
412
+ break;
413
+ case 'postToolUse':
414
+ await handlePostToolUse(input, config);
415
+ break;
416
+ case 'beforeShellExecution':
417
+ await handleBeforeShellExecution(input, config);
418
+ break;
419
+ case 'beforeMCPExecution':
420
+ await handleBeforeMCPExecution(input, config);
421
+ break;
422
+ case 'afterMCPExecution':
423
+ await handleAfterMCPExecution(input, config);
424
+ break;
425
+ case 'afterFileEdit':
426
+ await handleAfterFileEdit(input, config);
427
+ break;
428
+ case 'stop':
429
+ await handleStop(input, config);
430
+ break;
431
+ case 'subagentStart':
432
+ await handleSubagentLifecycle(input, config, 'start');
433
+ break;
434
+ case 'subagentStop':
435
+ await handleSubagentLifecycle(input, config, 'stop');
436
+ break;
437
+ case 'preCompact':
438
+ await handlePreCompact(input, config);
439
+ break;
440
+ default:
441
+ writeAllow();
442
+ }
443
+ }
444
+ (async () => {
445
+ try {
446
+ const input = await readStdin();
447
+ if (!input)
448
+ writeAllow();
449
+ await dispatch(input);
450
+ }
451
+ catch (err) {
452
+ stderr.write(`mnemonik-cursor-hook: dispatcher error (fail-open) - ${err instanceof Error ? err.message : String(err)}\n`);
453
+ writeAllow();
454
+ }
455
+ })();
456
+ //# sourceMappingURL=hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook.js","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Cursor hook entry shape (cursor.com/docs/hooks, plan §3.3).
4
+ *
5
+ * `loop_limit: null` is set explicitly for `stop` and `subagentStop` so the
6
+ * checkpoint-pressure followup chain is not capped at Cursor's default 5.
7
+ * Every other event keeps the default cap as a recursion safety net.
8
+ */
9
+ interface CursorHookEntry {
10
+ type: 'command';
11
+ command: string;
12
+ timeout?: number;
13
+ loop_limit?: number | null;
14
+ failClosed?: boolean;
15
+ matcher?: string;
16
+ }
17
+ interface BuildEntryOptions {
18
+ matcher?: string;
19
+ unlimitedLoop?: boolean;
20
+ }
21
+ declare function buildHookEntry(dispatcher: string, opts?: BuildEntryOptions): CursorHookEntry;
22
+ declare function isMnemonikEntry(entry: CursorHookEntry): boolean;
23
+ declare function patchEventEntries(existing: CursorHookEntry[] | undefined, entry: CursorHookEntry): CursorHookEntry[];
24
+ declare function parseArgs(argv: string[]): {
25
+ scope: 'project' | 'user';
26
+ };
27
+ export { buildHookEntry, isMnemonikEntry, patchEventEntries, parseArgs };
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, realpathSync } from 'node:fs';
3
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
4
+ import { dirname, join, resolve } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ const HOOK_TAG = 'mnemonik-cursor-hooks';
7
+ function resolveDispatcherPath() {
8
+ const here = fileURLToPath(import.meta.url);
9
+ return resolve(dirname(here), 'hook.js');
10
+ }
11
+ function buildHookEntry(dispatcher, opts = {}) {
12
+ const entry = {
13
+ type: 'command',
14
+ command: `node ${JSON.stringify(dispatcher)}`,
15
+ timeout: 5,
16
+ failClosed: false,
17
+ };
18
+ if (opts.matcher !== undefined)
19
+ entry.matcher = opts.matcher;
20
+ if (opts.unlimitedLoop)
21
+ entry.loop_limit = null;
22
+ return entry;
23
+ }
24
+ function isMnemonikEntry(entry) {
25
+ if (entry.matcher === HOOK_TAG)
26
+ return true;
27
+ return typeof entry.command === 'string' && entry.command.includes('cursor-hooks');
28
+ }
29
+ function patchEventEntries(existing, entry) {
30
+ const filtered = (existing ?? []).filter((e) => !isMnemonikEntry(e));
31
+ filtered.push(entry);
32
+ return filtered;
33
+ }
34
+ async function readHooksJson(path) {
35
+ if (!existsSync(path))
36
+ return { version: 1 };
37
+ try {
38
+ const raw = await readFile(path, 'utf8');
39
+ const parsed = JSON.parse(raw);
40
+ if (typeof parsed.version !== 'number')
41
+ parsed.version = 1;
42
+ return parsed;
43
+ }
44
+ catch (err) {
45
+ throw new Error(`Could not parse ${path}: ${err instanceof Error ? err.message : String(err)}`);
46
+ }
47
+ }
48
+ async function writeJson(path, value) {
49
+ await mkdir(dirname(path), { recursive: true });
50
+ await writeFile(path, JSON.stringify(value, null, 2) + '\n', 'utf8');
51
+ }
52
+ function resolveTargetPath(scope, cwd) {
53
+ if (scope === 'user') {
54
+ const home = process.env.HOME ?? process.env.USERPROFILE;
55
+ if (!home) {
56
+ throw new Error('Could not determine home directory for --scope=user install');
57
+ }
58
+ return join(home, '.cursor', 'hooks.json');
59
+ }
60
+ return join(cwd, '.cursor', 'hooks.json');
61
+ }
62
+ function parseArgs(argv) {
63
+ let scope = 'project';
64
+ for (const arg of argv) {
65
+ if (arg === '--scope=user')
66
+ scope = 'user';
67
+ else if (arg === '--scope=project')
68
+ scope = 'project';
69
+ }
70
+ return { scope };
71
+ }
72
+ async function main(argv) {
73
+ const { scope } = parseArgs(argv);
74
+ const cwd = process.cwd();
75
+ const hooksPath = resolveTargetPath(scope, cwd);
76
+ const dispatcher = resolveDispatcherPath();
77
+ if (!existsSync(dispatcher)) {
78
+ console.error(`mnemonik-cursor-hooks: dispatcher not found at ${dispatcher}. Did the package install correctly?`);
79
+ return 1;
80
+ }
81
+ const hooksJson = await readHooksJson(hooksPath);
82
+ const hooks = (hooksJson.hooks ?? {});
83
+ // The 12 events Mnemonik wires (plan §3.1, §5.2, §8).
84
+ //
85
+ // - preToolUse uses matcher "Write" — verified 2026-05-12 against
86
+ // cursor.com/docs/hooks. Cursor collapses all edit-class operations
87
+ // into "Write"; there is no "Edit" or "MultiEdit" tool name.
88
+ // - postToolUse uses matcher "Write|MCP:mnemonik.*" so the same handler
89
+ // sees both edit-class operations and Mnemonik MCP responses.
90
+ // - beforeMCPExecution and afterMCPExecution carry no matcher; the
91
+ // dispatcher filters to mnemonik.* tools at runtime.
92
+ // - stop and subagentStop set loop_limit: null so the checkpoint-pressure
93
+ // follow-up chain is not capped at Cursor's default 5.
94
+ hooks.sessionStart = patchEventEntries(hooks.sessionStart, buildHookEntry(dispatcher));
95
+ hooks.beforeSubmitPrompt = patchEventEntries(hooks.beforeSubmitPrompt, buildHookEntry(dispatcher));
96
+ hooks.preToolUse = patchEventEntries(hooks.preToolUse, buildHookEntry(dispatcher, { matcher: 'Write' }));
97
+ hooks.postToolUse = patchEventEntries(hooks.postToolUse, buildHookEntry(dispatcher, { matcher: 'Write|MCP:mnemonik.*' }));
98
+ hooks.beforeShellExecution = patchEventEntries(hooks.beforeShellExecution, buildHookEntry(dispatcher));
99
+ hooks.beforeMCPExecution = patchEventEntries(hooks.beforeMCPExecution, buildHookEntry(dispatcher));
100
+ hooks.afterMCPExecution = patchEventEntries(hooks.afterMCPExecution, buildHookEntry(dispatcher));
101
+ hooks.afterFileEdit = patchEventEntries(hooks.afterFileEdit, buildHookEntry(dispatcher));
102
+ hooks.stop = patchEventEntries(hooks.stop, buildHookEntry(dispatcher, { unlimitedLoop: true }));
103
+ hooks.subagentStart = patchEventEntries(hooks.subagentStart, buildHookEntry(dispatcher));
104
+ hooks.subagentStop = patchEventEntries(hooks.subagentStop, buildHookEntry(dispatcher, { unlimitedLoop: true }));
105
+ hooks.preCompact = patchEventEntries(hooks.preCompact, buildHookEntry(dispatcher));
106
+ hooksJson.hooks = hooks;
107
+ if (typeof hooksJson.version !== 'number')
108
+ hooksJson.version = 1;
109
+ await writeJson(hooksPath, hooksJson);
110
+ console.log([
111
+ `mnemonik-cursor-hooks: wired into ${hooksPath}`,
112
+ ` scope -> ${scope}`,
113
+ ` dispatcher -> ${dispatcher}`,
114
+ '',
115
+ 'Installed Cursor hooks only. This does not install or modify skills, rules, AGENTS.md, .mnemonik.json, or MCP config.',
116
+ 'MCP precheck (Cat 1-9 of the ordering-rule taxonomy) is server-driven via POST /api/v1/hooks/mcp-precheck.',
117
+ 'Bash policy reminders are server-driven via POST /api/v1/hooks/policy-reminder.',
118
+ 'Local irreducible deny-floor blocks three catastrophic patterns unconditionally: rm -rf / | ~ | $HOME, dd of=<whole-disk>, mkfs <whole-disk>.',
119
+ ].join('\n'));
120
+ return 0;
121
+ }
122
+ function isDirectExecution() {
123
+ const invoked = process.argv[1];
124
+ if (!invoked)
125
+ return false;
126
+ try {
127
+ return realpathSync(invoked) === realpathSync(fileURLToPath(import.meta.url));
128
+ }
129
+ catch {
130
+ return invoked === fileURLToPath(import.meta.url);
131
+ }
132
+ }
133
+ if (isDirectExecution()) {
134
+ main(process.argv.slice(2))
135
+ .then((code) => process.exit(code))
136
+ .catch((err) => {
137
+ console.error(`mnemonik-cursor-hooks: ${err instanceof Error ? err.message : String(err)}`);
138
+ process.exit(1);
139
+ });
140
+ }
141
+ export { buildHookEntry, isMnemonikEntry, patchEventEntries, parseArgs };
142
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,QAAQ,GAAG,uBAAuB,CAAC;AAwBzC,SAAS,qBAAqB;IAC5B,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5C,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;AAC3C,CAAC;AAOD,SAAS,cAAc,CAAC,UAAkB,EAAE,OAA0B,EAAE;IACtE,MAAM,KAAK,GAAoB;QAC7B,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,QAAQ,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE;QAC7C,OAAO,EAAE,CAAC;QACV,UAAU,EAAE,KAAK;KAClB,CAAC;IACF,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;QAAE,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC7D,IAAI,IAAI,CAAC,aAAa;QAAE,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;IAChD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,eAAe,CAAC,KAAsB;IAC7C,IAAI,KAAK,CAAC,OAAO,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC5C,OAAO,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;AACrF,CAAC;AAED,SAAS,iBAAiB,CACxB,QAAuC,EACvC,KAAsB;IAEtB,MAAM,QAAQ,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,IAAY;IACvC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAC7C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;QAClD,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ;YAAE,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;QAC3D,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClG,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,IAAY,EAAE,KAAc;IACnD,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAyB,EAAE,GAAW;IAC/D,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QACzD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;QACjF,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,SAAS,CAAC,IAAc;IAC/B,IAAI,KAAK,GAAuB,SAAS,CAAC;IAC1C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,KAAK,cAAc;YAAE,KAAK,GAAG,MAAM,CAAC;aACtC,IAAI,GAAG,KAAK,iBAAiB;YAAE,KAAK,GAAG,SAAS,CAAC;IACxD,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,IAAI,CAAC,IAAc;IAChC,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,qBAAqB,EAAE,CAAC;IAE3C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CACX,kDAAkD,UAAU,sCAAsC,CACnG,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,CAAsC,CAAC;IAE3E,sDAAsD;IACtD,EAAE;IACF,mEAAmE;IACnE,uEAAuE;IACvE,gEAAgE;IAChE,yEAAyE;IACzE,iEAAiE;IACjE,oEAAoE;IACpE,wDAAwD;IACxD,2EAA2E;IAC3E,0DAA0D;IAC1D,KAAK,CAAC,YAAY,GAAG,iBAAiB,CAAC,KAAK,CAAC,YAAY,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IACvF,KAAK,CAAC,kBAAkB,GAAG,iBAAiB,CAC1C,KAAK,CAAC,kBAAkB,EACxB,cAAc,CAAC,UAAU,CAAC,CAC3B,CAAC;IACF,KAAK,CAAC,UAAU,GAAG,iBAAiB,CAClC,KAAK,CAAC,UAAU,EAChB,cAAc,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CACjD,CAAC;IACF,KAAK,CAAC,WAAW,GAAG,iBAAiB,CACnC,KAAK,CAAC,WAAW,EACjB,cAAc,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC,CAChE,CAAC;IACF,KAAK,CAAC,oBAAoB,GAAG,iBAAiB,CAC5C,KAAK,CAAC,oBAAoB,EAC1B,cAAc,CAAC,UAAU,CAAC,CAC3B,CAAC;IACF,KAAK,CAAC,kBAAkB,GAAG,iBAAiB,CAC1C,KAAK,CAAC,kBAAkB,EACxB,cAAc,CAAC,UAAU,CAAC,CAC3B,CAAC;IACF,KAAK,CAAC,iBAAiB,GAAG,iBAAiB,CAAC,KAAK,CAAC,iBAAiB,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IACjG,KAAK,CAAC,aAAa,GAAG,iBAAiB,CAAC,KAAK,CAAC,aAAa,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IACzF,KAAK,CAAC,IAAI,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,EAAE,cAAc,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAChG,KAAK,CAAC,aAAa,GAAG,iBAAiB,CAAC,KAAK,CAAC,aAAa,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IACzF,KAAK,CAAC,YAAY,GAAG,iBAAiB,CACpC,KAAK,CAAC,YAAY,EAClB,cAAc,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CACpD,CAAC;IACF,KAAK,CAAC,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,UAAU,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAEnF,SAAS,CAAC,KAAK,GAAG,KAAK,CAAC;IACxB,IAAI,OAAO,SAAS,CAAC,OAAO,KAAK,QAAQ;QAAE,SAAS,CAAC,OAAO,GAAG,CAAC,CAAC;IACjE,MAAM,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAEtC,OAAO,CAAC,GAAG,CACT;QACE,qCAAqC,SAAS,EAAE;QAChD,qBAAqB,KAAK,EAAE;QAC5B,qBAAqB,UAAU,EAAE;QACjC,EAAE;QACF,uHAAuH;QACvH,4GAA4G;QAC5G,iFAAiF;QACjF,+IAA+I;KAChJ,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,iBAAiB;IACxB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,OAAO,CAAC,KAAK,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAChF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,KAAK,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpD,CAAC;AACH,CAAC;AAED,IAAI,iBAAiB,EAAE,EAAE,CAAC;IACxB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SACxB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAClC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QACtB,OAAO,CAAC,KAAK,CAAC,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC;AAED,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,SAAS,EAAE,CAAC"}