@rama_nigg/open-cursor 2.3.5 → 2.3.6

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 CHANGED
@@ -27,6 +27,9 @@ Add to `~/.config/opencode/opencode.json`:
27
27
  "cursor-acp": {
28
28
  "name": "Cursor ACP",
29
29
  "npm": "@ai-sdk/openai-compatible",
30
+ "options": {
31
+ "baseURL": "http://127.0.0.1:32124/v1"
32
+ },
30
33
  "models": {
31
34
  "cursor-acp/auto": { "name": "Auto" },
32
35
  "cursor-acp/composer-1.5": { "name": "Composer 1.5" },
package/dist/index.js CHANGED
@@ -17448,13 +17448,13 @@ function createToolLoopGuard(messages, maxRepeat) {
17448
17448
  }
17449
17449
  const strictFingerprint = `${toolCall.function.name}|${argShape}|${errorClass}`;
17450
17450
  const coarseFingerprint = `${toolCall.function.name}|${errorClass}`;
17451
- return evaluateWithFingerprints(errorClass, strictFingerprint, coarseFingerprint, counts, coarseCounts, maxRepeat, coarseMaxRepeat);
17451
+ return evaluateWithFingerprints(toolCall.function.name, errorClass, strictFingerprint, coarseFingerprint, counts, coarseCounts, maxRepeat, coarseMaxRepeat);
17452
17452
  },
17453
17453
  evaluateValidation(toolCall, validationSignature) {
17454
17454
  const normalizedSignature = normalizeValidationSignature(validationSignature);
17455
17455
  const strictFingerprint = `${toolCall.function.name}|schema:${normalizedSignature}|validation`;
17456
17456
  const coarseFingerprint = `${toolCall.function.name}|validation`;
17457
- return evaluateWithFingerprints("validation", strictFingerprint, coarseFingerprint, validationCounts, validationCoarseCounts, maxRepeat, coarseMaxRepeat);
17457
+ return evaluateWithFingerprints(toolCall.function.name, "validation", strictFingerprint, coarseFingerprint, validationCounts, validationCoarseCounts, maxRepeat, coarseMaxRepeat);
17458
17458
  },
17459
17459
  resetFingerprint(fingerprint) {
17460
17460
  counts.delete(fingerprint);
@@ -17685,7 +17685,7 @@ function normalizeValidationSignature(signature) {
17685
17685
  const normalized = signature.trim().toLowerCase();
17686
17686
  return normalized.length > 0 ? normalized : "invalid";
17687
17687
  }
17688
- function evaluateWithFingerprints(errorClass, strictFingerprint, coarseFingerprint, strictCounts, coarseCounts, maxRepeat, coarseMaxRepeat) {
17688
+ function evaluateWithFingerprints(toolName, errorClass, strictFingerprint, coarseFingerprint, strictCounts, coarseCounts, maxRepeat, coarseMaxRepeat) {
17689
17689
  if (errorClass === "success") {
17690
17690
  return {
17691
17691
  fingerprint: strictFingerprint,
@@ -17698,9 +17698,20 @@ function evaluateWithFingerprints(errorClass, strictFingerprint, coarseFingerpri
17698
17698
  }
17699
17699
  const strictRepeatCount = (strictCounts.get(strictFingerprint) ?? 0) + 1;
17700
17700
  strictCounts.set(strictFingerprint, strictRepeatCount);
17701
+ const strictTriggered = strictRepeatCount > maxRepeat;
17702
+ const isExplorationTool = EXPLORATION_TOOLS.has(toolName.toLowerCase());
17703
+ if (isExplorationTool) {
17704
+ return {
17705
+ fingerprint: strictFingerprint,
17706
+ repeatCount: strictRepeatCount,
17707
+ maxRepeat,
17708
+ errorClass,
17709
+ triggered: strictTriggered,
17710
+ tracked: true
17711
+ };
17712
+ }
17701
17713
  const coarseRepeatCount = (coarseCounts.get(coarseFingerprint) ?? 0) + 1;
17702
17714
  coarseCounts.set(coarseFingerprint, coarseRepeatCount);
17703
- const strictTriggered = strictRepeatCount > maxRepeat;
17704
17715
  const coarseTriggered = coarseRepeatCount > coarseMaxRepeat;
17705
17716
  const preferCoarseFingerprint = coarseTriggered && !strictTriggered;
17706
17717
  return {
@@ -17791,7 +17802,7 @@ function containsAny(text, patterns) {
17791
17802
  function isRecord4(value) {
17792
17803
  return typeof value === "object" && value !== null && !Array.isArray(value);
17793
17804
  }
17794
- var UNKNOWN_AS_SUCCESS_TOOLS, COARSE_LIMIT_MULTIPLIER = 3;
17805
+ var UNKNOWN_AS_SUCCESS_TOOLS, EXPLORATION_TOOLS, COARSE_LIMIT_MULTIPLIER = 3;
17795
17806
  var init_tool_loop_guard = __esm(() => {
17796
17807
  UNKNOWN_AS_SUCCESS_TOOLS = new Set([
17797
17808
  "bash",
@@ -17803,9 +17814,19 @@ var init_tool_loop_guard = __esm(() => {
17803
17814
  "ls",
17804
17815
  "glob",
17805
17816
  "stat",
17806
- "webfetch",
17807
17817
  "mkdir",
17808
- "rm"
17818
+ "rm",
17819
+ "webfetch",
17820
+ "semsearch",
17821
+ "readlints"
17822
+ ]);
17823
+ EXPLORATION_TOOLS = new Set([
17824
+ "read",
17825
+ "grep",
17826
+ "glob",
17827
+ "ls",
17828
+ "stat",
17829
+ "semsearch"
17809
17830
  ]);
17810
17831
  });
17811
17832
 
@@ -17448,13 +17448,13 @@ function createToolLoopGuard(messages, maxRepeat) {
17448
17448
  }
17449
17449
  const strictFingerprint = `${toolCall.function.name}|${argShape}|${errorClass}`;
17450
17450
  const coarseFingerprint = `${toolCall.function.name}|${errorClass}`;
17451
- return evaluateWithFingerprints(errorClass, strictFingerprint, coarseFingerprint, counts, coarseCounts, maxRepeat, coarseMaxRepeat);
17451
+ return evaluateWithFingerprints(toolCall.function.name, errorClass, strictFingerprint, coarseFingerprint, counts, coarseCounts, maxRepeat, coarseMaxRepeat);
17452
17452
  },
17453
17453
  evaluateValidation(toolCall, validationSignature) {
17454
17454
  const normalizedSignature = normalizeValidationSignature(validationSignature);
17455
17455
  const strictFingerprint = `${toolCall.function.name}|schema:${normalizedSignature}|validation`;
17456
17456
  const coarseFingerprint = `${toolCall.function.name}|validation`;
17457
- return evaluateWithFingerprints("validation", strictFingerprint, coarseFingerprint, validationCounts, validationCoarseCounts, maxRepeat, coarseMaxRepeat);
17457
+ return evaluateWithFingerprints(toolCall.function.name, "validation", strictFingerprint, coarseFingerprint, validationCounts, validationCoarseCounts, maxRepeat, coarseMaxRepeat);
17458
17458
  },
17459
17459
  resetFingerprint(fingerprint) {
17460
17460
  counts.delete(fingerprint);
@@ -17685,7 +17685,7 @@ function normalizeValidationSignature(signature) {
17685
17685
  const normalized = signature.trim().toLowerCase();
17686
17686
  return normalized.length > 0 ? normalized : "invalid";
17687
17687
  }
17688
- function evaluateWithFingerprints(errorClass, strictFingerprint, coarseFingerprint, strictCounts, coarseCounts, maxRepeat, coarseMaxRepeat) {
17688
+ function evaluateWithFingerprints(toolName, errorClass, strictFingerprint, coarseFingerprint, strictCounts, coarseCounts, maxRepeat, coarseMaxRepeat) {
17689
17689
  if (errorClass === "success") {
17690
17690
  return {
17691
17691
  fingerprint: strictFingerprint,
@@ -17698,9 +17698,20 @@ function evaluateWithFingerprints(errorClass, strictFingerprint, coarseFingerpri
17698
17698
  }
17699
17699
  const strictRepeatCount = (strictCounts.get(strictFingerprint) ?? 0) + 1;
17700
17700
  strictCounts.set(strictFingerprint, strictRepeatCount);
17701
+ const strictTriggered = strictRepeatCount > maxRepeat;
17702
+ const isExplorationTool = EXPLORATION_TOOLS.has(toolName.toLowerCase());
17703
+ if (isExplorationTool) {
17704
+ return {
17705
+ fingerprint: strictFingerprint,
17706
+ repeatCount: strictRepeatCount,
17707
+ maxRepeat,
17708
+ errorClass,
17709
+ triggered: strictTriggered,
17710
+ tracked: true
17711
+ };
17712
+ }
17701
17713
  const coarseRepeatCount = (coarseCounts.get(coarseFingerprint) ?? 0) + 1;
17702
17714
  coarseCounts.set(coarseFingerprint, coarseRepeatCount);
17703
- const strictTriggered = strictRepeatCount > maxRepeat;
17704
17715
  const coarseTriggered = coarseRepeatCount > coarseMaxRepeat;
17705
17716
  const preferCoarseFingerprint = coarseTriggered && !strictTriggered;
17706
17717
  return {
@@ -17791,7 +17802,7 @@ function containsAny(text, patterns) {
17791
17802
  function isRecord4(value) {
17792
17803
  return typeof value === "object" && value !== null && !Array.isArray(value);
17793
17804
  }
17794
- var UNKNOWN_AS_SUCCESS_TOOLS, COARSE_LIMIT_MULTIPLIER = 3;
17805
+ var UNKNOWN_AS_SUCCESS_TOOLS, EXPLORATION_TOOLS, COARSE_LIMIT_MULTIPLIER = 3;
17795
17806
  var init_tool_loop_guard = __esm(() => {
17796
17807
  UNKNOWN_AS_SUCCESS_TOOLS = new Set([
17797
17808
  "bash",
@@ -17803,9 +17814,19 @@ var init_tool_loop_guard = __esm(() => {
17803
17814
  "ls",
17804
17815
  "glob",
17805
17816
  "stat",
17806
- "webfetch",
17807
17817
  "mkdir",
17808
- "rm"
17818
+ "rm",
17819
+ "webfetch",
17820
+ "semsearch",
17821
+ "readlints"
17822
+ ]);
17823
+ EXPLORATION_TOOLS = new Set([
17824
+ "read",
17825
+ "grep",
17826
+ "glob",
17827
+ "ls",
17828
+ "stat",
17829
+ "semsearch"
17809
17830
  ]);
17810
17831
  });
17811
17832
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rama_nigg/open-cursor",
3
- "version": "2.3.5",
3
+ "version": "2.3.6",
4
4
  "description": "No prompt limits. No broken streams. Full thinking + tool support. Your Cursor subscription, properly integrated.",
5
5
  "type": "module",
6
6
  "main": "dist/plugin-entry.js",
@@ -10,6 +10,7 @@ type ToolLoopErrorClass =
10
10
  | "unknown";
11
11
 
12
12
  const UNKNOWN_AS_SUCCESS_TOOLS = new Set([
13
+ // Core filesystem tools
13
14
  "bash",
14
15
  "shell",
15
16
  "read",
@@ -19,9 +20,27 @@ const UNKNOWN_AS_SUCCESS_TOOLS = new Set([
19
20
  "ls",
20
21
  "glob",
21
22
  "stat",
22
- "webfetch",
23
23
  "mkdir",
24
24
  "rm",
25
+ // Web/network tools
26
+ "webfetch",
27
+ // cursor-agent specific tools (passthrough, but should not trigger loop guard)
28
+ // Discovered via tests/experiments/ harness - see docs/cursor-agent-tools.md
29
+ "semsearch", // semantic code search
30
+ "readlints", // lint/diagnostic reader
31
+ ]);
32
+
33
+ // Exploratory tools that commonly iterate over many files/patterns.
34
+ // These are exempt from COARSE fingerprint tracking (tool|errorClass) to allow
35
+ // legitimate multi-file exploration. Strict fingerprints (tool|args|errorClass)
36
+ // still apply to catch identical repeated failures.
37
+ const EXPLORATION_TOOLS = new Set([
38
+ "read",
39
+ "grep",
40
+ "glob",
41
+ "ls",
42
+ "stat",
43
+ "semsearch",
25
44
  ]);
26
45
 
27
46
  export interface ToolLoopGuardDecision {
@@ -125,6 +144,7 @@ export function createToolLoopGuard(
125
144
  const coarseFingerprint = `${toolCall.function.name}|${errorClass}`;
126
145
 
127
146
  return evaluateWithFingerprints(
147
+ toolCall.function.name,
128
148
  errorClass,
129
149
  strictFingerprint,
130
150
  coarseFingerprint,
@@ -140,6 +160,7 @@ export function createToolLoopGuard(
140
160
  const strictFingerprint = `${toolCall.function.name}|schema:${normalizedSignature}|validation`;
141
161
  const coarseFingerprint = `${toolCall.function.name}|validation`;
142
162
  return evaluateWithFingerprints(
163
+ toolCall.function.name,
143
164
  "validation",
144
165
  strictFingerprint,
145
166
  coarseFingerprint,
@@ -456,6 +477,7 @@ function normalizeValidationSignature(signature: string): string {
456
477
  }
457
478
 
458
479
  function evaluateWithFingerprints(
480
+ toolName: string,
459
481
  errorClass: ToolLoopErrorClass,
460
482
  strictFingerprint: string,
461
483
  coarseFingerprint: string,
@@ -477,9 +499,22 @@ function evaluateWithFingerprints(
477
499
 
478
500
  const strictRepeatCount = (strictCounts.get(strictFingerprint) ?? 0) + 1;
479
501
  strictCounts.set(strictFingerprint, strictRepeatCount);
502
+ const strictTriggered = strictRepeatCount > maxRepeat;
503
+
504
+ const isExplorationTool = EXPLORATION_TOOLS.has(toolName.toLowerCase());
505
+ if (isExplorationTool) {
506
+ return {
507
+ fingerprint: strictFingerprint,
508
+ repeatCount: strictRepeatCount,
509
+ maxRepeat,
510
+ errorClass,
511
+ triggered: strictTriggered,
512
+ tracked: true,
513
+ };
514
+ }
515
+
480
516
  const coarseRepeatCount = (coarseCounts.get(coarseFingerprint) ?? 0) + 1;
481
517
  coarseCounts.set(coarseFingerprint, coarseRepeatCount);
482
- const strictTriggered = strictRepeatCount > maxRepeat;
483
518
  const coarseTriggered = coarseRepeatCount > coarseMaxRepeat;
484
519
  const preferCoarseFingerprint = coarseTriggered && !strictTriggered;
485
520
  return {