@melihmucuk/leash 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -143,6 +143,27 @@ var CommandAnalyzer = class {
143
143
  const expanded = this.pathValidator.expand(path);
144
144
  return resolveBase ? resolve2(resolveBase, expanded) : expanded;
145
145
  }
146
+ /**
147
+ * Strip heredoc content from command before analyzing redirects.
148
+ * Handles: <<EOF, <<'EOF', <<"EOF", <<-EOF
149
+ */
150
+ stripHeredocs(command) {
151
+ const heredocStart = /<<-?\s*(['"]?)(\w+)\1/g;
152
+ let result = command;
153
+ let match;
154
+ while ((match = heredocStart.exec(command)) !== null) {
155
+ const delimiter = match[2];
156
+ const endPattern = new RegExp(`\\n\\t*${delimiter}\\s*(?:\\n|$)`);
157
+ const startIndex = match.index;
158
+ const contentAfterStart = command.slice(match.index + match[0].length);
159
+ const endMatch = endPattern.exec(contentAfterStart);
160
+ if (endMatch) {
161
+ const endIndex = match.index + match[0].length + endMatch.index + endMatch[0].length;
162
+ result = result.slice(0, startIndex) + result.slice(endIndex);
163
+ }
164
+ }
165
+ return result;
166
+ }
146
167
  isPathAllowed(path, allowDevicePaths, resolveBase) {
147
168
  const resolved = this.resolvePath(path, resolveBase);
148
169
  if (this.pathValidator.isWithinWorkingDir(resolved)) return true;
@@ -269,7 +290,8 @@ var CommandAnalyzer = class {
269
290
  return commands;
270
291
  }
271
292
  checkRedirects(command) {
272
- const matches = command.matchAll(REDIRECT_PATTERN);
293
+ const strippedCommand = this.stripHeredocs(command);
294
+ const matches = strippedCommand.matchAll(REDIRECT_PATTERN);
273
295
  for (const match of matches) {
274
296
  const path = match[1] || match[2] || match[3];
275
297
  if (!path || path.startsWith("&")) {
@@ -325,7 +347,11 @@ var CommandAnalyzer = class {
325
347
  reason: `Command "${name}" targets path outside working directory: ${path}`
326
348
  };
327
349
  }
328
- const result = this.checkProtectedPath(path, `Command "${name}"`, resolveBase);
350
+ const result = this.checkProtectedPath(
351
+ path,
352
+ `Command "${name}"`,
353
+ resolveBase
354
+ );
329
355
  if (result.blocked) return result;
330
356
  }
331
357
  }
@@ -337,7 +363,10 @@ var CommandAnalyzer = class {
337
363
  if (!this.isPathAllowed(dest, true, resolveBase)) {
338
364
  return {
339
365
  blocked: true,
340
- reason: `Command "cp" targets path outside working directory: ${this.resolvePath(dest, resolveBase)}`
366
+ reason: `Command "cp" targets path outside working directory: ${this.resolvePath(
367
+ dest,
368
+ resolveBase
369
+ )}`
341
370
  };
342
371
  }
343
372
  return this.checkProtectedPath(dest, 'Command "cp"', resolveBase);
@@ -349,7 +378,10 @@ var CommandAnalyzer = class {
349
378
  if (!this.isPathAllowed(dest, true, resolveBase)) {
350
379
  return {
351
380
  blocked: true,
352
- reason: `Command "dd" targets path outside working directory: ${this.resolvePath(dest, resolveBase)}`
381
+ reason: `Command "dd" targets path outside working directory: ${this.resolvePath(
382
+ dest,
383
+ resolveBase
384
+ )}`
353
385
  };
354
386
  }
355
387
  return this.checkProtectedPath(dest, 'Command "dd"', resolveBase);
@@ -361,7 +393,10 @@ var CommandAnalyzer = class {
361
393
  if (!this.isPathAllowed(dest, true, resolveBase)) {
362
394
  return {
363
395
  blocked: true,
364
- reason: `Command "mv" targets path outside working directory: ${this.resolvePath(dest, resolveBase)}`
396
+ reason: `Command "mv" targets path outside working directory: ${this.resolvePath(
397
+ dest,
398
+ resolveBase
399
+ )}`
365
400
  };
366
401
  }
367
402
  const destResult = this.checkProtectedPath(
@@ -374,7 +409,10 @@ var CommandAnalyzer = class {
374
409
  if (!this.isPathAllowed(source, false, resolveBase)) {
375
410
  return {
376
411
  blocked: true,
377
- reason: `Command "mv" targets path outside working directory: ${this.resolvePath(source, resolveBase)}`
412
+ reason: `Command "mv" targets path outside working directory: ${this.resolvePath(
413
+ source,
414
+ resolveBase
415
+ )}`
378
416
  };
379
417
  }
380
418
  const sourceResult = this.checkProtectedPath(
@@ -391,7 +429,10 @@ var CommandAnalyzer = class {
391
429
  if (!this.isPathAllowed(path, false, resolveBase)) {
392
430
  return {
393
431
  blocked: true,
394
- reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(path, resolveBase)}`
432
+ reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(
433
+ path,
434
+ resolveBase
435
+ )}`
395
436
  };
396
437
  }
397
438
  const result = this.checkProtectedPath(
@@ -409,7 +450,10 @@ var CommandAnalyzer = class {
409
450
  if (!this.isPathAllowed(path, allowDevicePaths, resolveBase)) {
410
451
  return {
411
452
  blocked: true,
412
- reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(path, resolveBase)}`
453
+ reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(
454
+ path,
455
+ resolveBase
456
+ )}`
413
457
  };
414
458
  }
415
459
  const result = this.checkProtectedPath(
@@ -143,6 +143,27 @@ var CommandAnalyzer = class {
143
143
  const expanded = this.pathValidator.expand(path);
144
144
  return resolveBase ? resolve2(resolveBase, expanded) : expanded;
145
145
  }
146
+ /**
147
+ * Strip heredoc content from command before analyzing redirects.
148
+ * Handles: <<EOF, <<'EOF', <<"EOF", <<-EOF
149
+ */
150
+ stripHeredocs(command) {
151
+ const heredocStart = /<<-?\s*(['"]?)(\w+)\1/g;
152
+ let result = command;
153
+ let match;
154
+ while ((match = heredocStart.exec(command)) !== null) {
155
+ const delimiter = match[2];
156
+ const endPattern = new RegExp(`\\n\\t*${delimiter}\\s*(?:\\n|$)`);
157
+ const startIndex = match.index;
158
+ const contentAfterStart = command.slice(match.index + match[0].length);
159
+ const endMatch = endPattern.exec(contentAfterStart);
160
+ if (endMatch) {
161
+ const endIndex = match.index + match[0].length + endMatch.index + endMatch[0].length;
162
+ result = result.slice(0, startIndex) + result.slice(endIndex);
163
+ }
164
+ }
165
+ return result;
166
+ }
146
167
  isPathAllowed(path, allowDevicePaths, resolveBase) {
147
168
  const resolved = this.resolvePath(path, resolveBase);
148
169
  if (this.pathValidator.isWithinWorkingDir(resolved)) return true;
@@ -269,7 +290,8 @@ var CommandAnalyzer = class {
269
290
  return commands;
270
291
  }
271
292
  checkRedirects(command) {
272
- const matches = command.matchAll(REDIRECT_PATTERN);
293
+ const strippedCommand = this.stripHeredocs(command);
294
+ const matches = strippedCommand.matchAll(REDIRECT_PATTERN);
273
295
  for (const match of matches) {
274
296
  const path = match[1] || match[2] || match[3];
275
297
  if (!path || path.startsWith("&")) {
@@ -325,7 +347,11 @@ var CommandAnalyzer = class {
325
347
  reason: `Command "${name}" targets path outside working directory: ${path}`
326
348
  };
327
349
  }
328
- const result = this.checkProtectedPath(path, `Command "${name}"`, resolveBase);
350
+ const result = this.checkProtectedPath(
351
+ path,
352
+ `Command "${name}"`,
353
+ resolveBase
354
+ );
329
355
  if (result.blocked) return result;
330
356
  }
331
357
  }
@@ -337,7 +363,10 @@ var CommandAnalyzer = class {
337
363
  if (!this.isPathAllowed(dest, true, resolveBase)) {
338
364
  return {
339
365
  blocked: true,
340
- reason: `Command "cp" targets path outside working directory: ${this.resolvePath(dest, resolveBase)}`
366
+ reason: `Command "cp" targets path outside working directory: ${this.resolvePath(
367
+ dest,
368
+ resolveBase
369
+ )}`
341
370
  };
342
371
  }
343
372
  return this.checkProtectedPath(dest, 'Command "cp"', resolveBase);
@@ -349,7 +378,10 @@ var CommandAnalyzer = class {
349
378
  if (!this.isPathAllowed(dest, true, resolveBase)) {
350
379
  return {
351
380
  blocked: true,
352
- reason: `Command "dd" targets path outside working directory: ${this.resolvePath(dest, resolveBase)}`
381
+ reason: `Command "dd" targets path outside working directory: ${this.resolvePath(
382
+ dest,
383
+ resolveBase
384
+ )}`
353
385
  };
354
386
  }
355
387
  return this.checkProtectedPath(dest, 'Command "dd"', resolveBase);
@@ -361,7 +393,10 @@ var CommandAnalyzer = class {
361
393
  if (!this.isPathAllowed(dest, true, resolveBase)) {
362
394
  return {
363
395
  blocked: true,
364
- reason: `Command "mv" targets path outside working directory: ${this.resolvePath(dest, resolveBase)}`
396
+ reason: `Command "mv" targets path outside working directory: ${this.resolvePath(
397
+ dest,
398
+ resolveBase
399
+ )}`
365
400
  };
366
401
  }
367
402
  const destResult = this.checkProtectedPath(
@@ -374,7 +409,10 @@ var CommandAnalyzer = class {
374
409
  if (!this.isPathAllowed(source, false, resolveBase)) {
375
410
  return {
376
411
  blocked: true,
377
- reason: `Command "mv" targets path outside working directory: ${this.resolvePath(source, resolveBase)}`
412
+ reason: `Command "mv" targets path outside working directory: ${this.resolvePath(
413
+ source,
414
+ resolveBase
415
+ )}`
378
416
  };
379
417
  }
380
418
  const sourceResult = this.checkProtectedPath(
@@ -391,7 +429,10 @@ var CommandAnalyzer = class {
391
429
  if (!this.isPathAllowed(path, false, resolveBase)) {
392
430
  return {
393
431
  blocked: true,
394
- reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(path, resolveBase)}`
432
+ reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(
433
+ path,
434
+ resolveBase
435
+ )}`
395
436
  };
396
437
  }
397
438
  const result = this.checkProtectedPath(
@@ -409,7 +450,10 @@ var CommandAnalyzer = class {
409
450
  if (!this.isPathAllowed(path, allowDevicePaths, resolveBase)) {
410
451
  return {
411
452
  blocked: true,
412
- reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(path, resolveBase)}`
453
+ reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(
454
+ path,
455
+ resolveBase
456
+ )}`
413
457
  };
414
458
  }
415
459
  const result = this.checkProtectedPath(
@@ -141,6 +141,27 @@ var CommandAnalyzer = class {
141
141
  const expanded = this.pathValidator.expand(path);
142
142
  return resolveBase ? resolve2(resolveBase, expanded) : expanded;
143
143
  }
144
+ /**
145
+ * Strip heredoc content from command before analyzing redirects.
146
+ * Handles: <<EOF, <<'EOF', <<"EOF", <<-EOF
147
+ */
148
+ stripHeredocs(command) {
149
+ const heredocStart = /<<-?\s*(['"]?)(\w+)\1/g;
150
+ let result = command;
151
+ let match;
152
+ while ((match = heredocStart.exec(command)) !== null) {
153
+ const delimiter = match[2];
154
+ const endPattern = new RegExp(`\\n\\t*${delimiter}\\s*(?:\\n|$)`);
155
+ const startIndex = match.index;
156
+ const contentAfterStart = command.slice(match.index + match[0].length);
157
+ const endMatch = endPattern.exec(contentAfterStart);
158
+ if (endMatch) {
159
+ const endIndex = match.index + match[0].length + endMatch.index + endMatch[0].length;
160
+ result = result.slice(0, startIndex) + result.slice(endIndex);
161
+ }
162
+ }
163
+ return result;
164
+ }
144
165
  isPathAllowed(path, allowDevicePaths, resolveBase) {
145
166
  const resolved = this.resolvePath(path, resolveBase);
146
167
  if (this.pathValidator.isWithinWorkingDir(resolved)) return true;
@@ -267,7 +288,8 @@ var CommandAnalyzer = class {
267
288
  return commands;
268
289
  }
269
290
  checkRedirects(command) {
270
- const matches = command.matchAll(REDIRECT_PATTERN);
291
+ const strippedCommand = this.stripHeredocs(command);
292
+ const matches = strippedCommand.matchAll(REDIRECT_PATTERN);
271
293
  for (const match of matches) {
272
294
  const path = match[1] || match[2] || match[3];
273
295
  if (!path || path.startsWith("&")) {
@@ -323,7 +345,11 @@ var CommandAnalyzer = class {
323
345
  reason: `Command "${name}" targets path outside working directory: ${path}`
324
346
  };
325
347
  }
326
- const result = this.checkProtectedPath(path, `Command "${name}"`, resolveBase);
348
+ const result = this.checkProtectedPath(
349
+ path,
350
+ `Command "${name}"`,
351
+ resolveBase
352
+ );
327
353
  if (result.blocked) return result;
328
354
  }
329
355
  }
@@ -335,7 +361,10 @@ var CommandAnalyzer = class {
335
361
  if (!this.isPathAllowed(dest, true, resolveBase)) {
336
362
  return {
337
363
  blocked: true,
338
- reason: `Command "cp" targets path outside working directory: ${this.resolvePath(dest, resolveBase)}`
364
+ reason: `Command "cp" targets path outside working directory: ${this.resolvePath(
365
+ dest,
366
+ resolveBase
367
+ )}`
339
368
  };
340
369
  }
341
370
  return this.checkProtectedPath(dest, 'Command "cp"', resolveBase);
@@ -347,7 +376,10 @@ var CommandAnalyzer = class {
347
376
  if (!this.isPathAllowed(dest, true, resolveBase)) {
348
377
  return {
349
378
  blocked: true,
350
- reason: `Command "dd" targets path outside working directory: ${this.resolvePath(dest, resolveBase)}`
379
+ reason: `Command "dd" targets path outside working directory: ${this.resolvePath(
380
+ dest,
381
+ resolveBase
382
+ )}`
351
383
  };
352
384
  }
353
385
  return this.checkProtectedPath(dest, 'Command "dd"', resolveBase);
@@ -359,7 +391,10 @@ var CommandAnalyzer = class {
359
391
  if (!this.isPathAllowed(dest, true, resolveBase)) {
360
392
  return {
361
393
  blocked: true,
362
- reason: `Command "mv" targets path outside working directory: ${this.resolvePath(dest, resolveBase)}`
394
+ reason: `Command "mv" targets path outside working directory: ${this.resolvePath(
395
+ dest,
396
+ resolveBase
397
+ )}`
363
398
  };
364
399
  }
365
400
  const destResult = this.checkProtectedPath(
@@ -372,7 +407,10 @@ var CommandAnalyzer = class {
372
407
  if (!this.isPathAllowed(source, false, resolveBase)) {
373
408
  return {
374
409
  blocked: true,
375
- reason: `Command "mv" targets path outside working directory: ${this.resolvePath(source, resolveBase)}`
410
+ reason: `Command "mv" targets path outside working directory: ${this.resolvePath(
411
+ source,
412
+ resolveBase
413
+ )}`
376
414
  };
377
415
  }
378
416
  const sourceResult = this.checkProtectedPath(
@@ -389,7 +427,10 @@ var CommandAnalyzer = class {
389
427
  if (!this.isPathAllowed(path, false, resolveBase)) {
390
428
  return {
391
429
  blocked: true,
392
- reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(path, resolveBase)}`
430
+ reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(
431
+ path,
432
+ resolveBase
433
+ )}`
393
434
  };
394
435
  }
395
436
  const result = this.checkProtectedPath(
@@ -407,7 +448,10 @@ var CommandAnalyzer = class {
407
448
  if (!this.isPathAllowed(path, allowDevicePaths, resolveBase)) {
408
449
  return {
409
450
  blocked: true,
410
- reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(path, resolveBase)}`
451
+ reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(
452
+ path,
453
+ resolveBase
454
+ )}`
411
455
  };
412
456
  }
413
457
  const result = this.checkProtectedPath(
package/dist/pi/leash.js CHANGED
@@ -141,6 +141,27 @@ var CommandAnalyzer = class {
141
141
  const expanded = this.pathValidator.expand(path);
142
142
  return resolveBase ? resolve2(resolveBase, expanded) : expanded;
143
143
  }
144
+ /**
145
+ * Strip heredoc content from command before analyzing redirects.
146
+ * Handles: <<EOF, <<'EOF', <<"EOF", <<-EOF
147
+ */
148
+ stripHeredocs(command) {
149
+ const heredocStart = /<<-?\s*(['"]?)(\w+)\1/g;
150
+ let result = command;
151
+ let match;
152
+ while ((match = heredocStart.exec(command)) !== null) {
153
+ const delimiter = match[2];
154
+ const endPattern = new RegExp(`\\n\\t*${delimiter}\\s*(?:\\n|$)`);
155
+ const startIndex = match.index;
156
+ const contentAfterStart = command.slice(match.index + match[0].length);
157
+ const endMatch = endPattern.exec(contentAfterStart);
158
+ if (endMatch) {
159
+ const endIndex = match.index + match[0].length + endMatch.index + endMatch[0].length;
160
+ result = result.slice(0, startIndex) + result.slice(endIndex);
161
+ }
162
+ }
163
+ return result;
164
+ }
144
165
  isPathAllowed(path, allowDevicePaths, resolveBase) {
145
166
  const resolved = this.resolvePath(path, resolveBase);
146
167
  if (this.pathValidator.isWithinWorkingDir(resolved)) return true;
@@ -267,7 +288,8 @@ var CommandAnalyzer = class {
267
288
  return commands;
268
289
  }
269
290
  checkRedirects(command) {
270
- const matches = command.matchAll(REDIRECT_PATTERN);
291
+ const strippedCommand = this.stripHeredocs(command);
292
+ const matches = strippedCommand.matchAll(REDIRECT_PATTERN);
271
293
  for (const match of matches) {
272
294
  const path = match[1] || match[2] || match[3];
273
295
  if (!path || path.startsWith("&")) {
@@ -323,7 +345,11 @@ var CommandAnalyzer = class {
323
345
  reason: `Command "${name}" targets path outside working directory: ${path}`
324
346
  };
325
347
  }
326
- const result = this.checkProtectedPath(path, `Command "${name}"`, resolveBase);
348
+ const result = this.checkProtectedPath(
349
+ path,
350
+ `Command "${name}"`,
351
+ resolveBase
352
+ );
327
353
  if (result.blocked) return result;
328
354
  }
329
355
  }
@@ -335,7 +361,10 @@ var CommandAnalyzer = class {
335
361
  if (!this.isPathAllowed(dest, true, resolveBase)) {
336
362
  return {
337
363
  blocked: true,
338
- reason: `Command "cp" targets path outside working directory: ${this.resolvePath(dest, resolveBase)}`
364
+ reason: `Command "cp" targets path outside working directory: ${this.resolvePath(
365
+ dest,
366
+ resolveBase
367
+ )}`
339
368
  };
340
369
  }
341
370
  return this.checkProtectedPath(dest, 'Command "cp"', resolveBase);
@@ -347,7 +376,10 @@ var CommandAnalyzer = class {
347
376
  if (!this.isPathAllowed(dest, true, resolveBase)) {
348
377
  return {
349
378
  blocked: true,
350
- reason: `Command "dd" targets path outside working directory: ${this.resolvePath(dest, resolveBase)}`
379
+ reason: `Command "dd" targets path outside working directory: ${this.resolvePath(
380
+ dest,
381
+ resolveBase
382
+ )}`
351
383
  };
352
384
  }
353
385
  return this.checkProtectedPath(dest, 'Command "dd"', resolveBase);
@@ -359,7 +391,10 @@ var CommandAnalyzer = class {
359
391
  if (!this.isPathAllowed(dest, true, resolveBase)) {
360
392
  return {
361
393
  blocked: true,
362
- reason: `Command "mv" targets path outside working directory: ${this.resolvePath(dest, resolveBase)}`
394
+ reason: `Command "mv" targets path outside working directory: ${this.resolvePath(
395
+ dest,
396
+ resolveBase
397
+ )}`
363
398
  };
364
399
  }
365
400
  const destResult = this.checkProtectedPath(
@@ -372,7 +407,10 @@ var CommandAnalyzer = class {
372
407
  if (!this.isPathAllowed(source, false, resolveBase)) {
373
408
  return {
374
409
  blocked: true,
375
- reason: `Command "mv" targets path outside working directory: ${this.resolvePath(source, resolveBase)}`
410
+ reason: `Command "mv" targets path outside working directory: ${this.resolvePath(
411
+ source,
412
+ resolveBase
413
+ )}`
376
414
  };
377
415
  }
378
416
  const sourceResult = this.checkProtectedPath(
@@ -389,7 +427,10 @@ var CommandAnalyzer = class {
389
427
  if (!this.isPathAllowed(path, false, resolveBase)) {
390
428
  return {
391
429
  blocked: true,
392
- reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(path, resolveBase)}`
430
+ reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(
431
+ path,
432
+ resolveBase
433
+ )}`
393
434
  };
394
435
  }
395
436
  const result = this.checkProtectedPath(
@@ -407,7 +448,10 @@ var CommandAnalyzer = class {
407
448
  if (!this.isPathAllowed(path, allowDevicePaths, resolveBase)) {
408
449
  return {
409
450
  blocked: true,
410
- reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(path, resolveBase)}`
451
+ reason: `Command "${baseCmd}" targets path outside working directory: ${this.resolvePath(
452
+ path,
453
+ resolveBase
454
+ )}`
411
455
  };
412
456
  }
413
457
  const result = this.checkProtectedPath(
@@ -522,17 +566,15 @@ async function checkForUpdates() {
522
566
  // packages/pi/leash.ts
523
567
  function leash_default(pi) {
524
568
  let analyzer = null;
525
- pi.on("session", async (event, ctx) => {
526
- if (event.reason === "start") {
527
- analyzer = new CommandAnalyzer(ctx.cwd);
528
- ctx.ui.notify("\u{1F512} Leash active", "info");
529
- const update = await checkForUpdates();
530
- if (update.hasUpdate) {
531
- ctx.ui.notify(
532
- `\u{1F504} Leash ${update.latestVersion} available. Run: leash --update (restart required)`,
533
- "warning"
534
- );
535
- }
569
+ pi.on("session_start", async (_event, ctx) => {
570
+ analyzer = new CommandAnalyzer(ctx.cwd);
571
+ ctx.ui.notify("\u{1F512} Leash active", "info");
572
+ const update = await checkForUpdates();
573
+ if (update.hasUpdate) {
574
+ ctx.ui.notify(
575
+ `\u{1F504} Leash ${update.latestVersion} available. Run: leash --update (restart required)`,
576
+ "warning"
577
+ );
536
578
  }
537
579
  });
538
580
  pi.on("tool_call", async (event, ctx) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@melihmucuk/leash",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "type": "module",
5
5
  "description": "Security guardrails for AI coding agents",
6
6
  "bin": {
@@ -49,8 +49,8 @@
49
49
  "build:factory": "esbuild packages/factory/leash.ts --bundle --outfile=dist/factory/leash.js --platform=node --format=esm"
50
50
  },
51
51
  "devDependencies": {
52
- "@mariozechner/pi-coding-agent": "^0.27.2",
53
- "@opencode-ai/plugin": "^1.0.191",
52
+ "@mariozechner/pi-coding-agent": "^0.31.0",
53
+ "@opencode-ai/plugin": "^1.0.224",
54
54
  "@types/node": "^22.19.3",
55
55
  "esbuild": "^0.27.2",
56
56
  "typescript": "^5.9.3"