@sdsrs/code-graph 0.68.0 → 0.69.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.
@@ -4,7 +4,7 @@
4
4
  "author": {
5
5
  "name": "sdsrs"
6
6
  },
7
- "version": "0.68.0",
7
+ "version": "0.69.0",
8
8
  "keywords": [
9
9
  "code-graph",
10
10
  "ast",
@@ -65,10 +65,20 @@ const SRC_PATH = new RegExp(`(?:^|\\s|["'])(${SRC_PREFIXES})/`);
65
65
  const SRC_PATH_TOKEN = new RegExp(`^(?:\\./)?(${SRC_PREFIXES})/`);
66
66
  const PIPE_INTO_GREP = /\|\s*(?:grep|rg|ag)\b/;
67
67
  const CG_INVOKED = /\bcode-graph-mcp\b/;
68
- // A file argument that ends in a config/lockfile extension AND no source-tree
69
- // path appears elsewhere grep is searching config, not code.
70
- const CONFIG_TARGET_ONLY =
71
- /(?:^|\s)[^\s|<>]*\.(toml|md|json|yml|yaml|lock|txt|cfg|env|gitignore|properties)(?:\s|$)/i;
68
+ // File argument(s) that end in a config/lockfile/data extension. If, after removing
69
+ // ALL of them, no source-tree path remains, the grep is searching config/data not code.
70
+ // v0.69 floor-hardening: (a) extended the extension list (ini/conf/xml/log/csv) and
71
+ // (b) made the strip GLOBAL so multiple data files (`grep X src/a.json src/b.json`) all
72
+ // peel off — previously only the first did, leaving the 2nd's `src/`-prefixed path to
73
+ // false-match SRC_PATH and fire. cg has no structural answer for these, so a deny is
74
+ // friction-without-value that teaches CODE_GRAPH_NO_BLOCK_GREP bypass (2026-06-23 reach
75
+ // audit: the unreached ~75% of greps are genuinely non-foldable — keep precision).
76
+ const NON_SOURCE_EXTS =
77
+ 'toml|md|json|yml|yaml|lock|txt|cfg|env|gitignore|properties|ini|conf|xml|log|csv';
78
+ const CONFIG_TARGET_ONLY = new RegExp(`(?:^|\\s)[^\\s|<>]*\\.(?:${NON_SOURCE_EXTS})(?:\\s|$)`, 'i');
79
+ // Global + trailing-lookahead variant for the strip: lookahead (not consume) so adjacent
80
+ // data-file tokens both match; global so every one is peeled before the SRC_PATH re-check.
81
+ const CONFIG_TARGET_STRIP = new RegExp(`(?:^|\\s)[^\\s|<>]*\\.(?:${NON_SOURCE_EXTS})(?=\\s|$)`, 'gi');
72
82
 
73
83
  function shouldHint(cmd) {
74
84
  if (!cmd || typeof cmd !== 'string') return false;
@@ -79,7 +89,7 @@ function shouldHint(cmd) {
79
89
  if (!SRC_PATH.test(cmd)) return false; // not against indexed source tree
80
90
  // If a config file appears AND no source path remains after stripping it, skip.
81
91
  if (CONFIG_TARGET_ONLY.test(cmd)) {
82
- const stripped = cmd.replace(CONFIG_TARGET_ONLY, ' ');
92
+ const stripped = cmd.replace(CONFIG_TARGET_STRIP, ' ');
83
93
  if (!SRC_PATH.test(stripped)) return false;
84
94
  }
85
95
  return true;
@@ -108,6 +108,42 @@ test('shouldHint: grep on a markdown changelog', () => {
108
108
  assert.equal(shouldHint('grep "v0.24" CHANGELOG.md'), false);
109
109
  });
110
110
 
111
+ // ── Floor (v0.69 hardening): non-foldable greps must NEVER deny/hint ──
112
+ // cg has no structural answer for these → a deny is friction-without-value that teaches
113
+ // CODE_GRAPH_NO_BLOCK_GREP bypass. 2026-06-23 reach audit: foldability (~24%) ≈
114
+ // interception (24%), so the floor (precision) is the lever — not reach expansion.
115
+
116
+ test('floor: grep on an external / non-indexed dir (/tmp clone) never fires', () => {
117
+ assert.equal(shouldHint('grep -rn "FooBar" /tmp/openwolf-analysis'), false);
118
+ assert.equal(shouldBlock('grep -rn "FooBar" /tmp/openwolf-analysis'), false);
119
+ });
120
+
121
+ test('floor: external path with an embedded src/ segment never fires', () => {
122
+ // SRC_PATH only matches a prefix at ^|\s|quote — `/tmp/clone/src/` is not a project path.
123
+ assert.equal(shouldHint('grep -rn "FooBar" /tmp/clone/src/'), false);
124
+ });
125
+
126
+ test('floor: a non-source data file (.log) under src/ never fires', () => {
127
+ assert.equal(shouldHint('grep "ErrorHandler" src/fixtures/app.log'), false);
128
+ assert.equal(shouldBlock('grep "ErrorHandler" src/fixtures/app.log'), false);
129
+ });
130
+
131
+ test('floor: ini/conf/xml/csv data files under src/ never fire', () => {
132
+ assert.equal(shouldHint('grep "FooBar" src/config.ini'), false);
133
+ assert.equal(shouldHint('grep "FooBar" src/app.conf'), false);
134
+ assert.equal(shouldHint('grep "FooBar" src/data.xml'), false);
135
+ assert.equal(shouldHint('grep "FooBar" src/rows.csv'), false);
136
+ });
137
+
138
+ test('floor: multiple config files under a src prefix all peel off → skip', () => {
139
+ // global strip (v0.69): pre-fix only the first .json peeled, the 2nd false-matched SRC_PATH.
140
+ assert.equal(shouldHint('grep "FooBar" src/a.json src/b.json'), false);
141
+ });
142
+
143
+ test('floor: mixed target (data file + real source file) STILL fires (no foldable miss)', () => {
144
+ assert.equal(shouldHint('grep -rn "FooBar" src/app.log src/handler.rs'), true);
145
+ });
146
+
111
147
  // ── Should NOT fire: not search tools ───────────────────────────────
112
148
 
113
149
  test('shouldHint: ls src/', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdsrs/code-graph",
3
- "version": "0.68.0",
3
+ "version": "0.69.0",
4
4
  "description": "MCP server that indexes codebases into an AST knowledge graph with semantic search, call graph traversal, and HTTP route tracing",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -35,10 +35,10 @@
35
35
  "node": ">=16"
36
36
  },
37
37
  "optionalDependencies": {
38
- "@sdsrs/code-graph-linux-x64": "0.68.0",
39
- "@sdsrs/code-graph-linux-arm64": "0.68.0",
40
- "@sdsrs/code-graph-darwin-x64": "0.68.0",
41
- "@sdsrs/code-graph-darwin-arm64": "0.68.0",
42
- "@sdsrs/code-graph-win32-x64": "0.68.0"
38
+ "@sdsrs/code-graph-linux-x64": "0.69.0",
39
+ "@sdsrs/code-graph-linux-arm64": "0.69.0",
40
+ "@sdsrs/code-graph-darwin-x64": "0.69.0",
41
+ "@sdsrs/code-graph-darwin-arm64": "0.69.0",
42
+ "@sdsrs/code-graph-win32-x64": "0.69.0"
43
43
  }
44
44
  }