veto-leash 0.1.3 → 1.0.1
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/README.md +111 -196
- package/dist/ast/builtins.d.ts +28 -0
- package/dist/ast/builtins.d.ts.map +1 -0
- package/dist/ast/builtins.js +361 -0
- package/dist/ast/builtins.js.map +1 -0
- package/dist/ast/checker.d.ts +17 -0
- package/dist/ast/checker.d.ts.map +1 -0
- package/dist/ast/checker.js +97 -0
- package/dist/ast/checker.js.map +1 -0
- package/dist/ast/index.d.ts +5 -0
- package/dist/ast/index.d.ts.map +1 -0
- package/dist/ast/index.js +7 -0
- package/dist/ast/index.js.map +1 -0
- package/dist/ast/parser.d.ts +55 -0
- package/dist/ast/parser.d.ts.map +1 -0
- package/dist/ast/parser.js +210 -0
- package/dist/ast/parser.js.map +1 -0
- package/dist/ast/query.d.ts +48 -0
- package/dist/ast/query.d.ts.map +1 -0
- package/dist/ast/query.js +102 -0
- package/dist/ast/query.js.map +1 -0
- package/dist/ast/validate-cli.d.ts +21 -0
- package/dist/ast/validate-cli.d.ts.map +1 -0
- package/dist/ast/validate-cli.js +73 -0
- package/dist/ast/validate-cli.js.map +1 -0
- package/dist/cli.js +105 -21
- package/dist/cli.js.map +1 -1
- package/dist/compiler/builtins.d.ts.map +1 -1
- package/dist/compiler/builtins.js +721 -4
- package/dist/compiler/builtins.js.map +1 -1
- package/dist/compiler/commands.d.ts +40 -0
- package/dist/compiler/commands.d.ts.map +1 -0
- package/dist/compiler/commands.js +311 -0
- package/dist/compiler/commands.js.map +1 -0
- package/dist/compiler/content.d.ts +160 -0
- package/dist/compiler/content.d.ts.map +1 -0
- package/dist/compiler/content.js +461 -0
- package/dist/compiler/content.js.map +1 -0
- package/dist/compiler/index.d.ts.map +1 -1
- package/dist/compiler/index.js +34 -7
- package/dist/compiler/index.js.map +1 -1
- package/dist/compiler/llm.d.ts.map +1 -1
- package/dist/compiler/llm.js +96 -9
- package/dist/compiler/llm.js.map +1 -1
- package/dist/compiler/prompt.d.ts +1 -1
- package/dist/compiler/prompt.d.ts.map +1 -1
- package/dist/compiler/prompt.js +247 -15
- package/dist/compiler/prompt.js.map +1 -1
- package/dist/config/leash-parser.d.ts +29 -0
- package/dist/config/leash-parser.d.ts.map +1 -0
- package/dist/config/leash-parser.js +70 -0
- package/dist/config/leash-parser.js.map +1 -0
- package/dist/config/loader.d.ts +2 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +18 -8
- package/dist/config/loader.js.map +1 -1
- package/dist/config/schema.d.ts +8 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +19 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/config/watcher.d.ts +18 -0
- package/dist/config/watcher.d.ts.map +1 -0
- package/dist/config/watcher.js +102 -0
- package/dist/config/watcher.js.map +1 -0
- package/dist/matcher.d.ts +18 -0
- package/dist/matcher.d.ts.map +1 -1
- package/dist/matcher.js +43 -0
- package/dist/matcher.js.map +1 -1
- package/dist/native/claude-code.d.ts.map +1 -1
- package/dist/native/claude-code.js +294 -50
- package/dist/native/claude-code.js.map +1 -1
- package/dist/native/cursor.d.ts +14 -1
- package/dist/native/cursor.d.ts.map +1 -1
- package/dist/native/cursor.js +340 -34
- package/dist/native/cursor.js.map +1 -1
- package/dist/native/index.d.ts +5 -0
- package/dist/native/index.d.ts.map +1 -1
- package/dist/native/index.js +56 -10
- package/dist/native/index.js.map +1 -1
- package/dist/native/opencode.d.ts.map +1 -1
- package/dist/native/opencode.js +15 -3
- package/dist/native/opencode.js.map +1 -1
- package/dist/native/validator.d.ts +15 -0
- package/dist/native/validator.d.ts.map +1 -0
- package/dist/native/validator.js +368 -0
- package/dist/native/validator.js.map +1 -0
- package/dist/types.d.ts +114 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/wrapper/daemon.d.ts.map +1 -1
- package/dist/wrapper/daemon.js +31 -2
- package/dist/wrapper/daemon.js.map +1 -1
- package/languages/tree-sitter-javascript.wasm +0 -0
- package/languages/tree-sitter-tsx.wasm +0 -0
- package/languages/tree-sitter-typescript.wasm +0 -0
- package/package.json +5 -2
package/dist/native/cursor.js
CHANGED
|
@@ -1,37 +1,344 @@
|
|
|
1
1
|
// src/native/cursor.ts
|
|
2
|
-
// Cursor integration via .
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
|
|
2
|
+
// Cursor CLI integration via hooks.json (v1.7+) and cli-config.json
|
|
3
|
+
//
|
|
4
|
+
// Based on official Cursor docs:
|
|
5
|
+
// - https://cursor.com/docs/agent/hooks
|
|
6
|
+
// - https://cursor.com/docs/cli/reference/permissions
|
|
7
|
+
//
|
|
8
|
+
// Two integration methods:
|
|
9
|
+
// 1. hooks.json - Real-time hook scripts for beforeShellExecution, afterFileEdit
|
|
10
|
+
// 2. cli-config.json - Permission tokens like Shell(npm), Write(*.ts)
|
|
11
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync, unlinkSync } from 'fs';
|
|
6
12
|
import { join } from 'path';
|
|
13
|
+
import { homedir } from 'os';
|
|
7
14
|
import { COLORS, SYMBOLS } from '../ui/colors.js';
|
|
15
|
+
const CURSOR_CONFIG_DIR = join(homedir(), '.cursor');
|
|
16
|
+
const CURSOR_HOOKS_FILE = join(CURSOR_CONFIG_DIR, 'hooks.json');
|
|
17
|
+
const CURSOR_CLI_CONFIG = join(CURSOR_CONFIG_DIR, 'cli-config.json');
|
|
18
|
+
const CURSOR_HOOKS_DIR = join(CURSOR_CONFIG_DIR, 'hooks', 'veto-leash');
|
|
19
|
+
const VETO_LEASH_CONFIG_DIR = join(homedir(), '.config', 'veto-leash');
|
|
20
|
+
const POLICIES_FILE = join(VETO_LEASH_CONFIG_DIR, 'policies.json');
|
|
21
|
+
// Also support project-level hooks
|
|
22
|
+
const PROJECT_CURSOR_DIR = '.cursor';
|
|
23
|
+
const PROJECT_HOOKS_FILE = join(PROJECT_CURSOR_DIR, 'hooks.json');
|
|
24
|
+
/**
|
|
25
|
+
* Install veto-leash for Cursor CLI
|
|
26
|
+
* Creates hooks.json and validator script
|
|
27
|
+
*/
|
|
28
|
+
export async function installCursorHooks(target = 'global') {
|
|
29
|
+
console.log(`\n${COLORS.info}Installing veto-leash for Cursor CLI (${target})...${COLORS.reset}\n`);
|
|
30
|
+
// Create hooks directory
|
|
31
|
+
mkdirSync(CURSOR_HOOKS_DIR, { recursive: true });
|
|
32
|
+
// Write the validator script
|
|
33
|
+
const validatorPath = join(CURSOR_HOOKS_DIR, 'validator.sh');
|
|
34
|
+
writeFileSync(validatorPath, VALIDATOR_SCRIPT, { mode: 0o755 });
|
|
35
|
+
console.log(` ${COLORS.success}${SYMBOLS.success}${COLORS.reset} Created validator: ${validatorPath}`);
|
|
36
|
+
// Write policies to hooks dir for fast access
|
|
37
|
+
const storedPolicies = loadStoredPolicies();
|
|
38
|
+
const policiesPath = join(CURSOR_HOOKS_DIR, 'policies.json');
|
|
39
|
+
writeFileSync(policiesPath, JSON.stringify(storedPolicies.policies.map(p => p.policy), null, 2));
|
|
40
|
+
console.log(` ${COLORS.success}${SYMBOLS.success}${COLORS.reset} Synced ${storedPolicies.policies.length} policies`);
|
|
41
|
+
// Update hooks.json
|
|
42
|
+
const hooksPath = target === 'global' ? CURSOR_HOOKS_FILE : PROJECT_HOOKS_FILE;
|
|
43
|
+
const hooksDir = target === 'global' ? CURSOR_CONFIG_DIR : PROJECT_CURSOR_DIR;
|
|
44
|
+
mkdirSync(hooksDir, { recursive: true });
|
|
45
|
+
let config = { version: 1, hooks: {} };
|
|
46
|
+
if (existsSync(hooksPath)) {
|
|
47
|
+
try {
|
|
48
|
+
config = JSON.parse(readFileSync(hooksPath, 'utf-8'));
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Start fresh
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Add veto-leash hooks
|
|
55
|
+
const hookCommand = `"${validatorPath}"`;
|
|
56
|
+
// beforeShellExecution - check commands (CAN block via permission: deny)
|
|
57
|
+
if (!config.hooks.beforeShellExecution) {
|
|
58
|
+
config.hooks.beforeShellExecution = [];
|
|
59
|
+
}
|
|
60
|
+
const shellHookIdx = config.hooks.beforeShellExecution.findIndex(h => h.command.includes('veto-leash'));
|
|
61
|
+
if (shellHookIdx >= 0) {
|
|
62
|
+
config.hooks.beforeShellExecution[shellHookIdx] = { command: hookCommand };
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
config.hooks.beforeShellExecution.push({ command: hookCommand });
|
|
66
|
+
}
|
|
67
|
+
// NOTE: Cursor's afterFileEdit is OBSERVATION ONLY - cannot block file edits.
|
|
68
|
+
// File protection is handled via cli-config.json Write() permissions instead.
|
|
69
|
+
// See: https://cursor.com/docs/agent/hooks
|
|
70
|
+
writeFileSync(hooksPath, JSON.stringify(config, null, 2));
|
|
71
|
+
console.log(` ${COLORS.success}${SYMBOLS.success}${COLORS.reset} Updated: ${hooksPath}`);
|
|
72
|
+
// Also update cli-config.json with permission rules
|
|
73
|
+
await updateCliConfig(storedPolicies.policies.map(p => p.policy));
|
|
74
|
+
console.log(`\n${COLORS.success}${SYMBOLS.success} veto-leash installed for Cursor CLI${COLORS.reset}\n`);
|
|
75
|
+
console.log(`${COLORS.dim}Restart Cursor to activate hooks.${COLORS.reset}\n`);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Update cli-config.json with permission rules
|
|
79
|
+
*/
|
|
80
|
+
async function updateCliConfig(policies) {
|
|
81
|
+
let config = {};
|
|
82
|
+
if (existsSync(CURSOR_CLI_CONFIG)) {
|
|
83
|
+
try {
|
|
84
|
+
config = JSON.parse(readFileSync(CURSOR_CLI_CONFIG, 'utf-8'));
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// Start fresh
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (!config.permissions) {
|
|
91
|
+
config.permissions = { allow: [], deny: [] };
|
|
92
|
+
}
|
|
93
|
+
if (!config.permissions.deny) {
|
|
94
|
+
config.permissions.deny = [];
|
|
95
|
+
}
|
|
96
|
+
// Remove existing veto-leash rules
|
|
97
|
+
config.permissions.deny = config.permissions.deny.filter(r => !r.includes('/* veto-leash */'));
|
|
98
|
+
// Add new rules from policies
|
|
99
|
+
for (const policy of policies) {
|
|
100
|
+
// Add command rules
|
|
101
|
+
if (policy.commandRules) {
|
|
102
|
+
for (const rule of policy.commandRules) {
|
|
103
|
+
for (const pattern of rule.block) {
|
|
104
|
+
// Convert command pattern to Cursor Shell() format
|
|
105
|
+
// "npm install*" -> Shell(npm)
|
|
106
|
+
const executable = pattern.split(' ')[0].replace('*', '');
|
|
107
|
+
if (executable) {
|
|
108
|
+
const cursorRule = `Shell(${executable}) /* veto-leash */`;
|
|
109
|
+
if (!config.permissions.deny.includes(cursorRule)) {
|
|
110
|
+
config.permissions.deny.push(cursorRule);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Add file rules
|
|
117
|
+
for (const pattern of policy.include) {
|
|
118
|
+
// Convert glob to Cursor Write() format
|
|
119
|
+
const cursorRule = `Write(${pattern}) /* veto-leash */`;
|
|
120
|
+
if (!config.permissions.deny.includes(cursorRule)) {
|
|
121
|
+
config.permissions.deny.push(cursorRule);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
mkdirSync(CURSOR_CONFIG_DIR, { recursive: true });
|
|
126
|
+
writeFileSync(CURSOR_CLI_CONFIG, JSON.stringify(config, null, 2));
|
|
127
|
+
console.log(` ${COLORS.success}${SYMBOLS.success}${COLORS.reset} Updated: ${CURSOR_CLI_CONFIG}`);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Uninstall veto-leash from Cursor CLI
|
|
131
|
+
*/
|
|
132
|
+
export async function uninstallCursorHooks(target = 'global') {
|
|
133
|
+
console.log(`\n${COLORS.info}Removing veto-leash from Cursor CLI...${COLORS.reset}\n`);
|
|
134
|
+
// Remove from hooks.json
|
|
135
|
+
const hooksPath = target === 'global' ? CURSOR_HOOKS_FILE : PROJECT_HOOKS_FILE;
|
|
136
|
+
if (existsSync(hooksPath)) {
|
|
137
|
+
try {
|
|
138
|
+
const config = JSON.parse(readFileSync(hooksPath, 'utf-8'));
|
|
139
|
+
if (config.hooks.beforeShellExecution) {
|
|
140
|
+
config.hooks.beforeShellExecution = config.hooks.beforeShellExecution.filter(h => !h.command.includes('veto-leash'));
|
|
141
|
+
}
|
|
142
|
+
// Also clean up any legacy afterFileEdit hooks (no longer used)
|
|
143
|
+
if (config.hooks.afterFileEdit) {
|
|
144
|
+
config.hooks.afterFileEdit = config.hooks.afterFileEdit.filter(h => !h.command.includes('veto-leash'));
|
|
145
|
+
}
|
|
146
|
+
writeFileSync(hooksPath, JSON.stringify(config, null, 2));
|
|
147
|
+
console.log(` ${COLORS.success}${SYMBOLS.success}${COLORS.reset} Removed hooks from ${hooksPath}`);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
console.log(` ${COLORS.warning}${SYMBOLS.warning}${COLORS.reset} Could not parse ${hooksPath}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Remove from cli-config.json
|
|
154
|
+
if (existsSync(CURSOR_CLI_CONFIG)) {
|
|
155
|
+
try {
|
|
156
|
+
const config = JSON.parse(readFileSync(CURSOR_CLI_CONFIG, 'utf-8'));
|
|
157
|
+
if (config.permissions?.deny) {
|
|
158
|
+
config.permissions.deny = config.permissions.deny.filter(r => !r.includes('/* veto-leash */'));
|
|
159
|
+
}
|
|
160
|
+
writeFileSync(CURSOR_CLI_CONFIG, JSON.stringify(config, null, 2));
|
|
161
|
+
console.log(` ${COLORS.success}${SYMBOLS.success}${COLORS.reset} Removed permissions from ${CURSOR_CLI_CONFIG}`);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
// Ignore
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
console.log(`\n${COLORS.success}${SYMBOLS.success} veto-leash removed from Cursor CLI${COLORS.reset}\n`);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Add a policy for Cursor
|
|
171
|
+
*/
|
|
172
|
+
export async function addCursorPolicy(policy, name) {
|
|
173
|
+
const policiesPath = join(CURSOR_HOOKS_DIR, 'policies.json');
|
|
174
|
+
let policies = [];
|
|
175
|
+
if (existsSync(policiesPath)) {
|
|
176
|
+
try {
|
|
177
|
+
policies = JSON.parse(readFileSync(policiesPath, 'utf-8'));
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
// Start fresh
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Check for duplicate by description
|
|
184
|
+
const existingIdx = policies.findIndex(p => p.description === policy.description);
|
|
185
|
+
if (existingIdx >= 0) {
|
|
186
|
+
policies[existingIdx] = policy;
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
policies.push(policy);
|
|
190
|
+
}
|
|
191
|
+
mkdirSync(CURSOR_HOOKS_DIR, { recursive: true });
|
|
192
|
+
writeFileSync(policiesPath, JSON.stringify(policies, null, 2));
|
|
193
|
+
}
|
|
194
|
+
function loadStoredPolicies() {
|
|
195
|
+
try {
|
|
196
|
+
if (existsSync(POLICIES_FILE)) {
|
|
197
|
+
return JSON.parse(readFileSync(POLICIES_FILE, 'utf-8'));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// Ignore
|
|
202
|
+
}
|
|
203
|
+
return { policies: [] };
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Bash validator script for Cursor hooks.
|
|
207
|
+
*
|
|
208
|
+
* Input (stdin): JSON with command, cwd, hook_event_name
|
|
209
|
+
* Output (stdout): JSON with permission, user_message, agent_message
|
|
210
|
+
*/
|
|
211
|
+
const VALIDATOR_SCRIPT = `#!/bin/bash
|
|
212
|
+
# veto-leash validator for Cursor CLI hooks
|
|
213
|
+
# Based on: https://cursor.com/docs/agent/hooks
|
|
214
|
+
|
|
215
|
+
set -euo pipefail
|
|
216
|
+
|
|
217
|
+
SCRIPT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
|
|
218
|
+
POLICIES_FILE="$SCRIPT_DIR/policies.json"
|
|
219
|
+
|
|
220
|
+
# Read JSON input
|
|
221
|
+
input=$(cat)
|
|
222
|
+
|
|
223
|
+
# Parse hook event
|
|
224
|
+
hook_event=$(echo "$input" | jq -r '.hook_event_name // empty')
|
|
225
|
+
|
|
226
|
+
# Check if policies file exists
|
|
227
|
+
if [ ! -f "$POLICIES_FILE" ]; then
|
|
228
|
+
echo '{"permission": "allow"}'
|
|
229
|
+
exit 0
|
|
230
|
+
fi
|
|
231
|
+
|
|
232
|
+
# Load policies
|
|
233
|
+
policies=$(cat "$POLICIES_FILE")
|
|
234
|
+
policy_count=$(echo "$policies" | jq 'length')
|
|
235
|
+
|
|
236
|
+
if [ "$policy_count" -eq 0 ]; then
|
|
237
|
+
echo '{"permission": "allow"}'
|
|
238
|
+
exit 0
|
|
239
|
+
fi
|
|
240
|
+
|
|
241
|
+
# Helper: Check if command matches pattern
|
|
242
|
+
command_matches() {
|
|
243
|
+
local cmd="$1"
|
|
244
|
+
local pattern="$2"
|
|
245
|
+
|
|
246
|
+
# Lowercase both
|
|
247
|
+
cmd=$(echo "$cmd" | tr '[:upper:]' '[:lower:]')
|
|
248
|
+
pattern=$(echo "$pattern" | tr '[:upper:]' '[:lower:]')
|
|
249
|
+
|
|
250
|
+
# Exact match
|
|
251
|
+
if [ "$cmd" = "$pattern" ]; then
|
|
252
|
+
return 0
|
|
253
|
+
fi
|
|
254
|
+
|
|
255
|
+
# Prefix match (pattern without wildcard)
|
|
256
|
+
if [[ ! "$pattern" == *"*"* ]]; then
|
|
257
|
+
if [[ "$cmd" == "$pattern "* ]] || [ "$cmd" = "$pattern" ]; then
|
|
258
|
+
return 0
|
|
259
|
+
fi
|
|
260
|
+
fi
|
|
261
|
+
|
|
262
|
+
# Wildcard match
|
|
263
|
+
# shellcheck disable=SC2053
|
|
264
|
+
if [[ "$cmd" == $pattern ]]; then
|
|
265
|
+
return 0
|
|
266
|
+
fi
|
|
267
|
+
|
|
268
|
+
return 1
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
# Handle beforeShellExecution
|
|
272
|
+
if [ "$hook_event" = "beforeShellExecution" ]; then
|
|
273
|
+
command=$(echo "$input" | jq -r '.command // empty')
|
|
274
|
+
|
|
275
|
+
if [ -z "$command" ]; then
|
|
276
|
+
echo '{"permission": "allow"}'
|
|
277
|
+
exit 0
|
|
278
|
+
fi
|
|
279
|
+
|
|
280
|
+
# Check each policy's commandRules
|
|
281
|
+
for i in $(seq 0 $((policy_count - 1))); do
|
|
282
|
+
policy=$(echo "$policies" | jq ".[$i]")
|
|
283
|
+
rules=$(echo "$policy" | jq -r '.commandRules // []')
|
|
284
|
+
rule_count=$(echo "$rules" | jq 'length')
|
|
285
|
+
|
|
286
|
+
for j in $(seq 0 $((rule_count - 1))); do
|
|
287
|
+
rule=$(echo "$rules" | jq ".[$j]")
|
|
288
|
+
blocks=$(echo "$rule" | jq -r '.block[]' 2>/dev/null || echo "")
|
|
289
|
+
|
|
290
|
+
for pattern in $blocks; do
|
|
291
|
+
if command_matches "$command" "$pattern"; then
|
|
292
|
+
reason=$(echo "$rule" | jq -r '.reason // "Blocked by policy"')
|
|
293
|
+
suggest=$(echo "$rule" | jq -r '.suggest // empty')
|
|
294
|
+
|
|
295
|
+
if [ -n "$suggest" ]; then
|
|
296
|
+
msg="veto-leash: Command blocked. $reason. Try: $suggest"
|
|
297
|
+
else
|
|
298
|
+
msg="veto-leash: Command blocked. $reason"
|
|
299
|
+
fi
|
|
300
|
+
|
|
301
|
+
echo "{\"permission\": \"deny\", \"user_message\": \"$msg\", \"agent_message\": \"$msg\"}"
|
|
302
|
+
exit 0
|
|
303
|
+
fi
|
|
304
|
+
done
|
|
305
|
+
done
|
|
306
|
+
done
|
|
307
|
+
fi
|
|
308
|
+
|
|
309
|
+
# NOTE: Cursor's afterFileEdit hook is OBSERVATION ONLY and cannot block edits.
|
|
310
|
+
# File protection is handled via cli-config.json Write() permissions.
|
|
311
|
+
# See: https://cursor.com/docs/agent/hooks
|
|
312
|
+
|
|
313
|
+
# Allow by default
|
|
314
|
+
echo '{"permission": "allow"}'
|
|
315
|
+
`;
|
|
316
|
+
// ============================================================================
|
|
317
|
+
// Legacy .cursorrules support (for older Cursor versions without hooks)
|
|
318
|
+
// ============================================================================
|
|
8
319
|
const CURSORRULES_FILE = '.cursorrules';
|
|
9
320
|
/**
|
|
10
321
|
* Install veto-leash instructions into .cursorrules
|
|
11
322
|
* Note: This only provides AI guidance, not enforcement.
|
|
12
|
-
* For actual enforcement, use wrapper mode: leash cursor "..."
|
|
13
323
|
*/
|
|
14
324
|
export async function installCursorRules() {
|
|
15
|
-
console.log(`\n${COLORS.info}Installing veto-leash
|
|
16
|
-
const policies = loadStoredPolicies();
|
|
325
|
+
console.log(`\n${COLORS.info}Installing veto-leash .cursorrules (legacy mode)...${COLORS.reset}\n`);
|
|
326
|
+
const policies = loadStoredPolicies().policies.map(p => p.policy);
|
|
17
327
|
if (policies.length === 0) {
|
|
18
328
|
console.log(`${COLORS.warning}${SYMBOLS.warning} No policies found. Add policies first:${COLORS.reset}`);
|
|
19
329
|
console.log(` ${COLORS.dim}leash add "don't delete test files"${COLORS.reset}\n`);
|
|
20
330
|
return;
|
|
21
331
|
}
|
|
22
332
|
const rulesContent = generateCursorRules(policies);
|
|
23
|
-
// Append or create .cursorrules
|
|
24
333
|
if (existsSync(CURSORRULES_FILE)) {
|
|
25
334
|
const existing = readFileSync(CURSORRULES_FILE, 'utf-8');
|
|
26
335
|
if (existing.includes('# veto-leash restrictions')) {
|
|
27
|
-
// Update existing section
|
|
28
336
|
const updated = existing.replace(/# veto-leash restrictions[\s\S]*?# end veto-leash/, rulesContent);
|
|
29
337
|
writeFileSync(CURSORRULES_FILE, updated);
|
|
30
338
|
console.log(` ${COLORS.success}${SYMBOLS.success}${COLORS.reset} Updated .cursorrules`);
|
|
31
339
|
}
|
|
32
340
|
else {
|
|
33
|
-
|
|
34
|
-
appendFileSync(CURSORRULES_FILE, '\n\n' + rulesContent);
|
|
341
|
+
writeFileSync(CURSORRULES_FILE, existing + '\n\n' + rulesContent);
|
|
35
342
|
console.log(` ${COLORS.success}${SYMBOLS.success}${COLORS.reset} Appended to .cursorrules`);
|
|
36
343
|
}
|
|
37
344
|
}
|
|
@@ -39,9 +346,9 @@ export async function installCursorRules() {
|
|
|
39
346
|
writeFileSync(CURSORRULES_FILE, rulesContent);
|
|
40
347
|
console.log(` ${COLORS.success}${SYMBOLS.success}${COLORS.reset} Created .cursorrules`);
|
|
41
348
|
}
|
|
42
|
-
console.log(`\n${COLORS.warning}${SYMBOLS.warning} Note:
|
|
43
|
-
console.log(`For actual enforcement
|
|
44
|
-
console.log(` ${COLORS.dim}leash cursor
|
|
349
|
+
console.log(`\n${COLORS.warning}${SYMBOLS.warning} Note: .cursorrules is AI guidance only.${COLORS.reset}`);
|
|
350
|
+
console.log(`For actual enforcement with Cursor 1.7+, use:`);
|
|
351
|
+
console.log(` ${COLORS.dim}leash install cursor${COLORS.reset}\n`);
|
|
45
352
|
}
|
|
46
353
|
function generateCursorRules(policies) {
|
|
47
354
|
const lines = ['# veto-leash restrictions'];
|
|
@@ -51,10 +358,23 @@ function generateCursorRules(policies) {
|
|
|
51
358
|
lines.push(`## ${policy.description}`);
|
|
52
359
|
lines.push(`Action: ${policy.action}`);
|
|
53
360
|
lines.push('');
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
361
|
+
if (policy.include.length > 0) {
|
|
362
|
+
lines.push('DO NOT perform this action on these files:');
|
|
363
|
+
for (const pattern of policy.include) {
|
|
364
|
+
lines.push(`- ${pattern}`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
if (policy.commandRules && policy.commandRules.length > 0) {
|
|
368
|
+
lines.push('');
|
|
369
|
+
lines.push('DO NOT run these commands:');
|
|
370
|
+
for (const rule of policy.commandRules) {
|
|
371
|
+
for (const pattern of rule.block) {
|
|
372
|
+
lines.push(`- ${pattern}`);
|
|
373
|
+
}
|
|
374
|
+
if (rule.suggest) {
|
|
375
|
+
lines.push(` Instead use: ${rule.suggest}`);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
58
378
|
}
|
|
59
379
|
if (policy.exclude.length > 0) {
|
|
60
380
|
lines.push('');
|
|
@@ -65,7 +385,7 @@ function generateCursorRules(policies) {
|
|
|
65
385
|
}
|
|
66
386
|
lines.push('');
|
|
67
387
|
}
|
|
68
|
-
lines.push('If
|
|
388
|
+
lines.push('If blocked, STOP and explain why you cannot proceed.');
|
|
69
389
|
lines.push('# end veto-leash');
|
|
70
390
|
return lines.join('\n');
|
|
71
391
|
}
|
|
@@ -84,22 +404,8 @@ export async function uninstallCursorRules() {
|
|
|
84
404
|
console.log(`${COLORS.success}${SYMBOLS.success} Removed veto-leash from .cursorrules${COLORS.reset}`);
|
|
85
405
|
}
|
|
86
406
|
else {
|
|
87
|
-
|
|
88
|
-
require('fs').unlinkSync(CURSORRULES_FILE);
|
|
407
|
+
unlinkSync(CURSORRULES_FILE);
|
|
89
408
|
console.log(`${COLORS.success}${SYMBOLS.success} Removed .cursorrules${COLORS.reset}`);
|
|
90
409
|
}
|
|
91
410
|
}
|
|
92
|
-
function loadStoredPolicies() {
|
|
93
|
-
const policiesFile = join(require('os').homedir(), '.config', 'veto-leash', 'policies.json');
|
|
94
|
-
try {
|
|
95
|
-
if (existsSync(policiesFile)) {
|
|
96
|
-
const data = JSON.parse(readFileSync(policiesFile, 'utf-8'));
|
|
97
|
-
return data.policies?.map((p) => p.policy) || [];
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
catch {
|
|
101
|
-
// Ignore
|
|
102
|
-
}
|
|
103
|
-
return [];
|
|
104
|
-
}
|
|
105
411
|
//# sourceMappingURL=cursor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/native/cursor.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,sCAAsC;AACtC,2EAA2E;AAC3E,wEAAwE;AAExE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAExC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,IAAI,sCAAsC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAEpF,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;IAEtC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,0CAA0C,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QACzG,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,GAAG,sCAAsC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;QACnF,OAAO;IACT,CAAC;IAED,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAEnD,gCAAgC;IAChC,IAAI,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACzD,IAAI,QAAQ,CAAC,QAAQ,CAAC,2BAA2B,CAAC,EAAE,CAAC;YACnD,0BAA0B;YAC1B,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAC9B,mDAAmD,EACnD,YAAY,CACb,CAAC;YACF,aAAa,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;YACzC,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,uBAAuB,CAAC,CAAC;QAC3F,CAAC;aAAM,CAAC;YACN,SAAS;YACT,cAAc,CAAC,gBAAgB,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC;YACxD,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,2BAA2B,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC;SAAM,CAAC;QACN,aAAa,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,uBAAuB,CAAC,CAAC;IAC3F,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,6DAA6D,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9H,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,GAAG,+BAA+B,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,mBAAmB,CAAC,QAAkB;IAC7C,MAAM,KAAK,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAC5C,KAAK,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;IAClE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;QAClE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEf,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;QAC7B,CAAC;QAED,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;YAC9C,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACrC,KAAK,CAAC,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,+FAA+F,CAAC,CAAC;IAC5G,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAE/B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,6BAA6B,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QACtE,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAC7B,yDAAyD,EACzD,EAAE,CACH,CAAC;IAEF,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QACnB,aAAa,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,wCAAwC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACzG,CAAC;SAAM,CAAC;QACN,iCAAiC;QACjC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,wBAAwB,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACzF,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB;IACzB,MAAM,YAAY,GAAG,IAAI,CACvB,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EACvB,SAAS,EACT,YAAY,EACZ,eAAe,CAChB,CAAC;IAEF,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;YAC7D,OAAO,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAqB,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACvE,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/native/cursor.ts"],"names":[],"mappings":"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"}
|
package/dist/native/index.d.ts
CHANGED
|
@@ -27,6 +27,11 @@ export declare function uninstallAgent(agentId: string, options?: {
|
|
|
27
27
|
* Add a policy to all installed native integrations
|
|
28
28
|
*/
|
|
29
29
|
export declare function addPolicyToAgents(policy: Policy, name: string): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Detect installed AI coding agents by checking for their config directories.
|
|
32
|
+
* Only returns agents with native hook support.
|
|
33
|
+
*/
|
|
34
|
+
export declare function detectInstalledAgents(): AgentInfo[];
|
|
30
35
|
export * from './claude-code.js';
|
|
31
36
|
export * from './opencode.js';
|
|
32
37
|
export * from './windsurf.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/native/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/native/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA+B1C,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,MAAM,EAAE,SAAS,EAkD7B,CAAC;AAEF;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAU5D;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,OAAO,CAAC,CA8ClB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,OAAO,CAAC,CAmClB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,SAAS,EAAE,CAmCnD;AAYD,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
package/dist/native/index.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
// src/native/index.ts
|
|
2
2
|
// Agent registry and unified interface for native integrations
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { homedir } from 'os';
|
|
3
6
|
import { COLORS, SYMBOLS } from '../ui/colors.js';
|
|
4
7
|
// Import all agent integrations
|
|
5
8
|
import { installClaudeCodeHook, addClaudeCodePolicy, uninstallClaudeCodeHook, } from './claude-code.js';
|
|
6
9
|
import { installOpenCodePermissions, uninstallOpenCodePermissions, savePolicy as saveOpenCodePolicy, } from './opencode.js';
|
|
7
10
|
import { installWindsurfHooks, addWindsurfPolicy, uninstallWindsurfHooks, } from './windsurf.js';
|
|
8
|
-
import {
|
|
11
|
+
import { installCursorHooks, uninstallCursorHooks, addCursorPolicy, uninstallCursorRules, } from './cursor.js';
|
|
9
12
|
import { installAiderConfig, uninstallAiderConfig, } from './aider.js';
|
|
10
13
|
export const AGENTS = [
|
|
11
14
|
{
|
|
@@ -13,35 +16,35 @@ export const AGENTS = [
|
|
|
13
16
|
name: 'Claude Code',
|
|
14
17
|
aliases: ['cc', 'claude', 'claude-code'],
|
|
15
18
|
hasNativeHooks: true,
|
|
16
|
-
description: 'PreToolUse hooks
|
|
19
|
+
description: 'PreToolUse hooks with AST validation (Bash/Write/Edit)',
|
|
17
20
|
},
|
|
18
21
|
{
|
|
19
22
|
id: 'opencode',
|
|
20
23
|
name: 'OpenCode',
|
|
21
24
|
aliases: ['oc', 'opencode'],
|
|
22
25
|
hasNativeHooks: true,
|
|
23
|
-
description: 'permission.bash rules
|
|
26
|
+
description: 'permission.bash deny rules (command-level only)',
|
|
24
27
|
},
|
|
25
28
|
{
|
|
26
29
|
id: 'windsurf',
|
|
27
30
|
name: 'Windsurf',
|
|
28
31
|
aliases: ['ws', 'windsurf', 'cascade'],
|
|
29
32
|
hasNativeHooks: true,
|
|
30
|
-
description: 'Cascade hooks
|
|
33
|
+
description: 'Cascade hooks: pre_write_code, pre_run_command (exit 2 blocks)',
|
|
31
34
|
},
|
|
32
35
|
{
|
|
33
36
|
id: 'cursor',
|
|
34
|
-
name: 'Cursor',
|
|
35
|
-
aliases: ['cursor'],
|
|
36
|
-
hasNativeHooks:
|
|
37
|
-
description: '
|
|
37
|
+
name: 'Cursor CLI',
|
|
38
|
+
aliases: ['cursor', 'cursor-cli'],
|
|
39
|
+
hasNativeHooks: true,
|
|
40
|
+
description: 'beforeShellExecution hooks + Write() permissions (v1.7+)',
|
|
38
41
|
},
|
|
39
42
|
{
|
|
40
43
|
id: 'aider',
|
|
41
44
|
name: 'Aider',
|
|
42
45
|
aliases: ['aider'],
|
|
43
46
|
hasNativeHooks: false,
|
|
44
|
-
description: '.aider.conf.yml read-only
|
|
47
|
+
description: '.aider.conf.yml read: option (read-only context)',
|
|
45
48
|
},
|
|
46
49
|
{
|
|
47
50
|
id: 'codex',
|
|
@@ -93,7 +96,7 @@ export async function installAgent(agentId, options = {}) {
|
|
|
93
96
|
await installWindsurfHooks(options.global ? 'user' : 'workspace');
|
|
94
97
|
return true;
|
|
95
98
|
case 'cursor':
|
|
96
|
-
await
|
|
99
|
+
await installCursorHooks(options.global ? 'global' : 'project');
|
|
97
100
|
return true;
|
|
98
101
|
case 'aider':
|
|
99
102
|
await installAiderConfig(options.global ? 'global' : 'project');
|
|
@@ -133,6 +136,8 @@ export async function uninstallAgent(agentId, options = {}) {
|
|
|
133
136
|
await uninstallWindsurfHooks(options.global ? 'user' : 'workspace');
|
|
134
137
|
return true;
|
|
135
138
|
case 'cursor':
|
|
139
|
+
await uninstallCursorHooks(options.global ? 'global' : 'project');
|
|
140
|
+
// Also clean up legacy .cursorrules
|
|
136
141
|
await uninstallCursorRules();
|
|
137
142
|
return true;
|
|
138
143
|
case 'aider':
|
|
@@ -153,6 +158,47 @@ export async function addPolicyToAgents(policy, name) {
|
|
|
153
158
|
await addClaudeCodePolicy(policy, name);
|
|
154
159
|
// Windsurf
|
|
155
160
|
await addWindsurfPolicy(policy, name);
|
|
161
|
+
// Cursor
|
|
162
|
+
await addCursorPolicy(policy, name);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Detect installed AI coding agents by checking for their config directories.
|
|
166
|
+
* Only returns agents with native hook support.
|
|
167
|
+
*/
|
|
168
|
+
export function detectInstalledAgents() {
|
|
169
|
+
const detected = [];
|
|
170
|
+
const home = homedir();
|
|
171
|
+
// Claude Code: ~/.claude/
|
|
172
|
+
if (existsSync(join(home, '.claude'))) {
|
|
173
|
+
const agent = AGENTS.find(a => a.id === 'claude-code');
|
|
174
|
+
if (agent)
|
|
175
|
+
detected.push(agent);
|
|
176
|
+
}
|
|
177
|
+
// OpenCode: ~/.opencode/
|
|
178
|
+
if (existsSync(join(home, '.opencode'))) {
|
|
179
|
+
const agent = AGENTS.find(a => a.id === 'opencode');
|
|
180
|
+
if (agent)
|
|
181
|
+
detected.push(agent);
|
|
182
|
+
}
|
|
183
|
+
// Cursor: ~/.cursor/
|
|
184
|
+
if (existsSync(join(home, '.cursor'))) {
|
|
185
|
+
const agent = AGENTS.find(a => a.id === 'cursor');
|
|
186
|
+
if (agent)
|
|
187
|
+
detected.push(agent);
|
|
188
|
+
}
|
|
189
|
+
// Windsurf: ~/.windsurf/ or ~/.codeium/
|
|
190
|
+
if (existsSync(join(home, '.windsurf')) || existsSync(join(home, '.codeium'))) {
|
|
191
|
+
const agent = AGENTS.find(a => a.id === 'windsurf');
|
|
192
|
+
if (agent)
|
|
193
|
+
detected.push(agent);
|
|
194
|
+
}
|
|
195
|
+
// Aider: check if .aider.conf.yml exists in home or cwd
|
|
196
|
+
if (existsSync(join(home, '.aider.conf.yml')) || existsSync('.aider.conf.yml')) {
|
|
197
|
+
const agent = AGENTS.find(a => a.id === 'aider');
|
|
198
|
+
if (agent)
|
|
199
|
+
detected.push(agent);
|
|
200
|
+
}
|
|
201
|
+
return detected;
|
|
156
202
|
}
|
|
157
203
|
function printSupportedAgents() {
|
|
158
204
|
console.log(`\nSupported agents:`);
|
package/dist/native/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/native/index.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,+DAA+D;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/native/index.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,+DAA+D;AAE/D,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAElD,gCAAgC;AAChC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,0BAA0B,EAC1B,4BAA4B,EAC5B,UAAU,IAAI,kBAAkB,GACjC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EAEf,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAUpB,MAAM,CAAC,MAAM,MAAM,GAAgB;IACjC;QACE,EAAE,EAAE,aAAa;QACjB,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,aAAa,CAAC;QACxC,cAAc,EAAE,IAAI;QACpB,WAAW,EAAE,wDAAwD;KACtE;IACD;QACE,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC;QAC3B,cAAc,EAAE,IAAI;QACpB,WAAW,EAAE,iDAAiD;KAC/D;IACD;QACE,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC;QACtC,cAAc,EAAE,IAAI;QACpB,WAAW,EAAE,gEAAgE;KAC9E;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC;QACjC,cAAc,EAAE,IAAI;QACpB,WAAW,EAAE,0DAA0D;KACxE;IACD;QACE,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,CAAC,OAAO,CAAC;QAClB,cAAc,EAAE,KAAK;QACrB,WAAW,EAAE,kDAAkD;KAChE;IACD;QACE,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC;QAC/B,cAAc,EAAE,KAAK;QACrB,WAAW,EAAE,gCAAgC;KAC9C;IACD;QACE,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC;QAClC,cAAc,EAAE,KAAK;QACrB,WAAW,EAAE,mCAAmC;KACjD;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,UAAU,GAAG,KAAK,EAAE,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAC/C,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAE7B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAe,EACf,UAAgC,EAAE;IAElC,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAEpC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,mBAAmB,OAAO,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1F,oBAAoB,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,QAAQ,KAAK,CAAC,EAAE,EAAE,CAAC;QACjB,KAAK,aAAa;YAChB,MAAM,qBAAqB,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC;QAEd,KAAK,UAAU;YACb,MAAM,0BAA0B,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACxE,OAAO,IAAI,CAAC;QAEd,KAAK,UAAU;YACb,MAAM,oBAAoB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;YAClE,OAAO,IAAI,CAAC;QAEd,KAAK,QAAQ;YACX,MAAM,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAChE,OAAO,IAAI,CAAC;QAEd,KAAK,OAAO;YACV,MAAM,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAChE,OAAO,IAAI,CAAC;QAEd,KAAK,OAAO;YACV,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,uCAAuC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YACxG,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;YACtD,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,GAAG,mCAAmC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;YAChF,OAAO,KAAK,CAAC;QAEf,KAAK,SAAS;YACZ,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,sCAAsC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YACvG,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,GAAG,6BAA6B,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;YAC1E,OAAO,KAAK,CAAC;QAEf;YACE,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,8BAA8B,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YACxG,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAe,EACf,UAAgC,EAAE;IAElC,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAEpC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,mBAAmB,OAAO,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1F,OAAO,KAAK,CAAC;IACf,CAAC;IAED,QAAQ,KAAK,CAAC,EAAE,EAAE,CAAC;QACjB,KAAK,aAAa;YAChB,MAAM,uBAAuB,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC;QAEd,KAAK,UAAU;YACb,MAAM,4BAA4B,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAC1E,OAAO,IAAI,CAAC;QAEd,KAAK,UAAU;YACb,MAAM,sBAAsB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;YACpE,OAAO,IAAI,CAAC;QAEd,KAAK,QAAQ;YACX,MAAM,oBAAoB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAClE,oCAAoC;YACpC,MAAM,oBAAoB,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QAEd,KAAK,OAAO;YACV,MAAM,oBAAoB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAClE,OAAO,IAAI,CAAC;QAEd;YACE,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,uCAAuC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YAC7F,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAc,EACd,IAAY;IAEZ,mCAAmC;IACnC,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAEjC,cAAc;IACd,MAAM,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAExC,WAAW;IACX,MAAM,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAEtC,SAAS;IACT,MAAM,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB;IACnC,MAAM,QAAQ,GAAgB,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,0BAA0B;IAC1B,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC;QACvD,IAAI,KAAK;YAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,yBAAyB;IACzB,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;QACpD,IAAI,KAAK;YAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,qBAAqB;IACrB,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;QAClD,IAAI,KAAK;YAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,wCAAwC;IACxC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;QAC9E,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;QACpD,IAAI,KAAK;YAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,wDAAwD;IACxD,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC,IAAI,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC/E,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;QACjD,IAAI,KAAK;YAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,oBAAoB;IAC3B,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,GAAG,SAAS,CAAC;QAC7F,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;IAC3H,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,+BAA+B;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../src/native/opencode.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../src/native/opencode.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA8G1C;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,MAAM,GAAE,QAAQ,GAAG,SAAqB,GACvC,OAAO,CAAC,IAAI,CAAC,CAqEf;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,IAAI,CAwBjD;AAED;;GAEG;AACH,wBAAsB,4BAA4B,CAChD,MAAM,GAAE,QAAQ,GAAG,SAAqB,GACvC,OAAO,CAAC,IAAI,CAAC,CAsCf;AAgBD;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAgBpE;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAiBnC"}
|