ast-search-python 1.4.1 → 1.5.0-beta.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/AGENTS.md CHANGED
@@ -94,6 +94,7 @@ JSON output includes `start`/`end` byte offsets and `source_full` (for multi-lin
94
94
  "col": 0,
95
95
  "start": 87,
96
96
  "end": 116,
97
+ "offsetEncoding": "bytes",
97
98
  "source": "logging.info(\"user logged in\")",
98
99
  "captures": {
99
100
  "fn": "logging.info",
@@ -103,10 +104,10 @@ JSON output includes `start`/`end` byte offsets and `source_full` (for multi-lin
103
104
  }
104
105
  ```
105
106
 
106
- - `start` / `end`: **byte offsets** from the start of the file (not UTF-16 character offsets as in the JS backend). For ASCII-only source these are equivalent; for non-ASCII source (e.g. Unicode identifiers or string literals), byte offsets and character offsets diverge — account for this when slicing file contents.
107
+ - `start` / `end`: character offsets from the start of the file. `offsetEncoding` is always `"bytes"` for Python matches (tree-sitter). For ASCII-only source, byte offsets and UTF-16 offsets are equivalent; for non-ASCII source (e.g. Unicode identifiers or string literals) they diverge — account for this when slicing file contents.
107
108
  - `source_full`: full text of the matched node. Only present when the match spans multiple lines (differs from `source`).
108
109
 
109
- ⚠️ **Python `start`/`end` are byte offsets; JS/TS `start`/`end` are UTF-16 character offsets.** When writing tools that consume both, use the `file`/`line`/`col` fields for display and treat `start`/`end` as language-specific.
110
+ ⚠️ **`offsetEncoding` differs by language: `"bytes"` for Python, `"utf16"` for JS/TS.** When writing tools that consume both, use `offsetEncoding` to determine how to interpret `start`/`end`, or use `file`/`line`/`col` for display and avoid `start`/`end` cross-language comparisons.
110
111
 
111
112
  All captures from a single pattern application are grouped onto one match — `@fn`, `@msg`, and `@call` from the same query match produce one result, not three.
112
113
 
package/build/query.js CHANGED
@@ -45,12 +45,31 @@ export function runTreeSitterQuery(ast, pattern, source, filePath, language, sho
45
45
  }
46
46
  return results;
47
47
  }
48
+ // Common tree-sitter error patterns and more actionable hints.
49
+ function enrichTreeSitterError(raw, pattern) {
50
+ const lines = [`Invalid tree-sitter query: ${raw}`];
51
+ // Detect "Invalid node type" — the most common authoring mistake
52
+ const nodeTypeMatch = raw.match(/Invalid node type[:\s]+["']?(\w+)["']?/i);
53
+ if (nodeTypeMatch) {
54
+ lines.push(`Hint: node type "${nodeTypeMatch[1]}" is not recognized by the Python grammar.`, `Use show_ast on a real .py file to discover the correct node names.`);
55
+ return lines.join("\n");
56
+ }
57
+ // Missing @ capture
58
+ if (!pattern.includes("@") && !raw.toLowerCase().includes("capture")) {
59
+ lines.push(`Hint: tree-sitter S-expressions require a capture name, e.g. "(function_definition) @fn".`, `Without @capture, no results are returned. The query engine may also reject bare S-expressions.`);
60
+ return lines.join("\n");
61
+ }
62
+ // Generic fallback guidance
63
+ lines.push(`Hint: use show_ast on a .py file to see the correct node types and property names before authoring a query.`, `Example valid queries: "(function_definition) @fn" | "(call) @_" | "(import_statement) @import"`);
64
+ return lines.join("\n");
65
+ }
48
66
  export function validateTreeSitterQuery(pattern, language) {
49
67
  try {
50
68
  assertValidPattern(pattern);
51
69
  language.query(pattern);
52
70
  }
53
71
  catch (e) {
54
- throw new Error(`Invalid tree-sitter query: ${e instanceof Error ? e.message : String(e)}`);
72
+ const raw = e instanceof Error ? e.message : String(e);
73
+ throw new Error(enrichTreeSitterError(raw, pattern));
55
74
  }
56
75
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ast-search-python",
3
- "version": "1.4.1",
3
+ "version": "1.5.0-beta.1",
4
4
  "description": "Python language plugin for ast-search",
5
5
  "type": "module",
6
6
  "main": "./build/index.js",
@@ -47,6 +47,6 @@
47
47
  "typescript": "^5.4.5"
48
48
  },
49
49
  "peerDependencies": {
50
- "ast-search-js": "^1.0.0"
50
+ "ast-search-js": "1.9.0-beta.1"
51
51
  }
52
52
  }