pi-revit 0.2.14 → 0.2.16
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/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,37 @@ Format follows [Keep a Changelog](https://keepachangelog.com/); version headers
|
|
|
7
7
|
Every published version gets an entry with **Added** / **Changed** / **Fixed** sections
|
|
8
8
|
describing what the user will notice — not internal refactors.
|
|
9
9
|
|
|
10
|
+
## [0.2.16] - 2026-08-21
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- `search_api_docs`: an accessor-spelling query combined with `kind: "method"` — e.g.
|
|
14
|
+
`Element.get_Parameter(BuiltInParameter)` filtered to methods — returned "no matches",
|
|
15
|
+
because the accessor rewrite found the documented member but the kind filter rejected it:
|
|
16
|
+
a C# `get_X`/`set_X` accessor is a method to the caller, while the XML documents the
|
|
17
|
+
underlying member as a property or indexer. For accessor-rewritten candidates the
|
|
18
|
+
`method` filter now also admits properties, and the result note says so. Found by an
|
|
19
|
+
agent under a stress test that filtered its doc query to methods. Two benchmark probes
|
|
20
|
+
added (the widening plus a real-method control).
|
|
21
|
+
|
|
22
|
+
Requires redeploying the Revit add-in (`scripts\deploy.ps1` with Revit closed, then
|
|
23
|
+
restart Revit).
|
|
24
|
+
|
|
25
|
+
## [0.2.15] - 2026-08-21
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
- `set_parameters`: the "parameter not found" error now mentions that display names are
|
|
29
|
+
localized and points to the language-independent BuiltInParameter enum name — the same
|
|
30
|
+
guidance `get_element_details` and `get_elements` already give. Previously it only
|
|
31
|
+
suggested the type-parameter cause, which sent the caller down the wrong path in
|
|
32
|
+
non-English UIs.
|
|
33
|
+
- `get_elements`: the "filter parameter not found on any probed element" warning now
|
|
34
|
+
appears only when the query returned zero matches — that is where it distinguishes
|
|
35
|
+
"unknown parameter name" from "no matching elements". Next to real matches it was noise
|
|
36
|
+
(an unscoped query's probe window can simply miss the elements that carry the parameter).
|
|
37
|
+
|
|
38
|
+
Requires redeploying the Revit add-in (`scripts\deploy.ps1` with Revit closed, then
|
|
39
|
+
restart Revit).
|
|
40
|
+
|
|
10
41
|
## [0.2.14] - 2026-08-21
|
|
11
42
|
|
|
12
43
|
### Fixed
|
package/package.json
CHANGED
|
@@ -31,8 +31,10 @@ else:
|
|
|
31
31
|
XML_PATH = candidates[-1]
|
|
32
32
|
|
|
33
33
|
LAT = []
|
|
34
|
-
def search(query, max_results=10):
|
|
35
|
-
|
|
34
|
+
def search(query, max_results=10, kind=None):
|
|
35
|
+
args = {"query": query, "max_results": max_results}
|
|
36
|
+
if kind: args["kind"] = kind
|
|
37
|
+
body = json.dumps(args).encode("utf-8")
|
|
36
38
|
url = f"{BASE}/tools/search_api_docs/execute?token={TOKEN}&timeout_ms=60000"
|
|
37
39
|
req = urllib.request.Request(url, data=body, headers={"content-type": "application/json"}, method="POST")
|
|
38
40
|
t0 = time.perf_counter()
|
|
@@ -180,8 +182,8 @@ R["B signature+spacing"] = B
|
|
|
180
182
|
|
|
181
183
|
# --------------------------------------------------------- C: complex syntax shapes
|
|
182
184
|
C = {"cases": []}
|
|
183
|
-
def probe(label, q, expect_nonzero=True):
|
|
184
|
-
try: matches, total = search(q)
|
|
185
|
+
def probe(label, q, expect_nonzero=True, kind=None):
|
|
186
|
+
try: matches, total = search(q, kind=kind)
|
|
185
187
|
except Exception as e:
|
|
186
188
|
C["cases"].append((label, q, f"ERROR {e}")); return
|
|
187
189
|
ok = (total > 0) if expect_nonzero else (total == 0)
|
|
@@ -213,6 +215,9 @@ probe("factory honesty control", "Document.Create.Banana", expect_nonzero=False)
|
|
|
213
215
|
probe("accessor indexer", "Element.get_Parameter(BuiltInParameter")
|
|
214
216
|
probe("accessor property", "Element.get_BoundingBox(View")
|
|
215
217
|
probe("literal get_ member", "LocationCurve.get_ElementsAtJoin")
|
|
218
|
+
# 0.2.16: kind=method on an accessor query admits the documented property
|
|
219
|
+
probe("accessor with kind=method", "Element.get_Parameter(BuiltInParameter", kind="method")
|
|
220
|
+
probe("kind=method control (real method)", "Wall.Create(Document, Curve", kind="method")
|
|
216
221
|
print("C done", flush=True)
|
|
217
222
|
R["C complex-syntax"] = C
|
|
218
223
|
|
|
@@ -147,7 +147,10 @@ namespace RevitBridge.Tools
|
|
|
147
147
|
string scope = DescribeScope(categoryInput, classInput, inActiveView);
|
|
148
148
|
|
|
149
149
|
if (countOnly && postPredicate is null)
|
|
150
|
-
|
|
150
|
+
{
|
|
151
|
+
int quickCount = CreateCollector().GetElementCount();
|
|
152
|
+
return CountResult(scope, quickCount, quickCount > 0 ? Array.Empty<string>() : filterWarnings);
|
|
153
|
+
}
|
|
151
154
|
|
|
152
155
|
var rows = countOnly ? null : new List<Dictionary<string, object?>>(Math.Min(limit, 256));
|
|
153
156
|
int total = 0;
|
|
@@ -160,6 +163,12 @@ namespace RevitBridge.Tools
|
|
|
160
163
|
total++;
|
|
161
164
|
}
|
|
162
165
|
|
|
166
|
+
// A found match proves the query worked: the not-found-on-probes warning is
|
|
167
|
+
// load-bearing only next to a zero, where it distinguishes 'unknown parameter
|
|
168
|
+
// name' from 'no matching elements'. Beside real matches it is just noise.
|
|
169
|
+
if (total > 0)
|
|
170
|
+
filterWarnings = Array.Empty<string>();
|
|
171
|
+
|
|
163
172
|
if (rows is null)
|
|
164
173
|
return CountResult(scope, total, filterWarnings);
|
|
165
174
|
|
|
@@ -142,17 +142,17 @@ namespace RevitBridge.Tools
|
|
|
142
142
|
// member, before giving up. Deterministic rewrites of an exact idiom — never
|
|
143
143
|
// applied unless the literal 'document.create.' / 'application.create.' prefix
|
|
144
144
|
// is present, so ordinary names like Wall.Create are untouched.
|
|
145
|
-
var candidates = new List<(string Query, string? Note)> { (q, null) };
|
|
145
|
+
var candidates = new List<(string Query, string? Note, bool AccessorRewrite)> { (q, null, false) };
|
|
146
146
|
foreach (string factory in new[] { "document.create.", "application.create." })
|
|
147
147
|
{
|
|
148
148
|
if (!q.StartsWith(factory, StringComparison.Ordinal))
|
|
149
149
|
continue;
|
|
150
150
|
string owner = factory[..(factory.IndexOf('.') + 1)]; // "document."
|
|
151
151
|
string rest = q[factory.Length..];
|
|
152
|
-
candidates.Add((owner + rest, $"'{owner}Create.*' is the Creation factory — matched as '{owner}{rest}'."));
|
|
152
|
+
candidates.Add((owner + rest, $"'{owner}Create.*' is the Creation factory — matched as '{owner}{rest}'.", false));
|
|
153
153
|
string bareMember = rest.Split('(')[0];
|
|
154
154
|
if (bareMember.Length > 0)
|
|
155
|
-
candidates.Add((bareMember, $"'{owner}Create.{bareMember}' is a Creation-factory call; its docs live on the factory class (e.g. ItemFactoryBase) — matched by member name '{bareMember}'."));
|
|
155
|
+
candidates.Add((bareMember, $"'{owner}Create.{bareMember}' is a Creation-factory call; its docs live on the factory class (e.g. ItemFactoryBase) — matched by member name '{bareMember}'.", false));
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
// C# spells property and indexer accessors 'get_X'/'set_X' (element.get_Parameter(...),
|
|
@@ -166,26 +166,33 @@ namespace RevitBridge.Tools
|
|
|
166
166
|
if (accessor.StartsWith("get_", StringComparison.Ordinal) || accessor.StartsWith("set_", StringComparison.Ordinal))
|
|
167
167
|
accessor = accessor["get_".Length..];
|
|
168
168
|
if (accessor != q)
|
|
169
|
-
candidates.Add((accessor, "'get_X' / 'set_X' is the C# accessor spelling of property or indexer 'X'; matched without the prefix."));
|
|
169
|
+
candidates.Add((accessor, "'get_X' / 'set_X' is the C# accessor spelling of property or indexer 'X'; matched without the prefix.", true));
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
foreach (var (candidate, note) in candidates)
|
|
172
|
+
foreach (var (candidate, note, accessorRewrite) in candidates)
|
|
173
173
|
{
|
|
174
|
-
|
|
174
|
+
// A C# accessor IS a method to the caller ('element.get_Parameter(...)'), but
|
|
175
|
+
// the XML documents the underlying member as a property/indexer — so an
|
|
176
|
+
// accessor-rewritten candidate lets kind=method admit properties too.
|
|
177
|
+
bool widenKind = accessorRewrite && kindFilter == 'M';
|
|
178
|
+
var (top, total) = RunScoring(index, candidate, kindFilter, maxResults, widenKind);
|
|
175
179
|
if (total > 0)
|
|
176
|
-
return (top, total,
|
|
180
|
+
return (top, total, widenKind
|
|
181
|
+
? note + " The 'method' kind filter also admitted properties here: accessors are documented as properties/indexers."
|
|
182
|
+
: note);
|
|
177
183
|
}
|
|
178
184
|
return (new List<ApiMember>(), 0, null);
|
|
179
185
|
}
|
|
180
186
|
|
|
181
|
-
private static (List<ApiMember> Top, int Total) RunScoring(DocIndex index, string q, char? kindFilter, int maxResults)
|
|
187
|
+
private static (List<ApiMember> Top, int Total) RunScoring(DocIndex index, string q, char? kindFilter, int maxResults, bool methodKindAdmitsProperties = false)
|
|
182
188
|
{
|
|
183
189
|
string[] words = q.Split(WordSeparators, StringSplitOptions.RemoveEmptyEntries);
|
|
184
190
|
|
|
185
191
|
var scored = new List<(ApiMember Member, int Score)>();
|
|
186
192
|
foreach (var member in index.Members)
|
|
187
193
|
{
|
|
188
|
-
if (kindFilter is { } kind && member.Kind != kind
|
|
194
|
+
if (kindFilter is { } kind && member.Kind != kind
|
|
195
|
+
&& !(methodKindAdmitsProperties && kind == 'M' && member.Kind == 'P'))
|
|
189
196
|
continue;
|
|
190
197
|
int score = Score(member, q, words);
|
|
191
198
|
if (score > 0)
|
|
@@ -156,7 +156,7 @@ namespace RevitBridge.Tools
|
|
|
156
156
|
{
|
|
157
157
|
if (nameTarget)
|
|
158
158
|
return SetElementName(element, update);
|
|
159
|
-
throw new InvalidOperationException($"Parameter '{update.ParameterInput}' not found on element {update.ElementId} ('{element.Name}'). Type parameters live on the element type — pass
|
|
159
|
+
throw new InvalidOperationException($"Parameter '{update.ParameterInput}' not found on element {update.ElementId} ('{element.Name}'). Display names are localized in non-English Revit UIs — prefer the language-independent BuiltInParameter enum name (e.g. ALL_MODEL_INSTANCE_COMMENTS; get_element_details reports each parameter's builtInParameter). Type parameters live on the element type — pass the type's id instead.");
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
if (parameter.IsReadOnly)
|