pi-revit 0.2.16 → 0.2.18

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,35 @@ 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.18] - 2026-08-21
11
+
12
+ ### Fixed
13
+ - When pi starts before Revit and the background rediscovery timer (rather than a `ping`
14
+ call) registers the bridge tools, the session is now told — the same announcement the
15
+ ping path has always given. Previously the tools appeared silently in the next system
16
+ prompt while nothing contradicted the session's earlier "Revit is not running", so the
17
+ agent could stay needlessly pessimistic. The note is queued for the next user prompt
18
+ and never interrupts. Extension-only change; the Revit add-in is unchanged (the
19
+ standard installer keeps both versions aligned).
20
+
21
+ ## [0.2.17] - 2026-08-21
22
+
23
+ ### Fixed
24
+ - The bridge's no-document check no longer counts linked documents. With only links
25
+ loaded, Revit does not pump the bridge's work queue, so a call could wait out its full
26
+ timeout instead of failing immediately with the clean "no active document" answer.
27
+
28
+ ### Changed
29
+ - Docs and tool descriptions describe localized parameter names generically instead of
30
+ quoting specific languages.
31
+ - The full search_api_docs benchmark (641 live queries against RevitAPI.xml ground truth)
32
+ was re-run on Revit 2025 at 0.2.16: 100% recall, 98.75% top-1 on exact names, 100%
33
+ spacing-variant agreement, 0 false positives across 99 adversarial mutations, 50/50
34
+ parameter docs, p50 10 ms -- no regression across the 0.2.13-0.2.16 search changes.
35
+
36
+ Requires redeploying the Revit add-in (`scripts\deploy.ps1` with Revit closed, then
37
+ restart Revit).
38
+
10
39
  ## [0.2.16] - 2026-08-21
11
40
 
12
41
  ### Fixed
@@ -372,7 +372,28 @@ export default async function revitConnector(pi: ExtensionAPI) {
372
372
  // Never block pi startup on Revit: keep retrying quietly in the background
373
373
  // and stop the moment discovery succeeds.
374
374
  const timer = setInterval(async () => {
375
- if (await discoverAndRegister()) clearInterval(timer);
375
+ if (!(await discoverAndRegister())) return;
376
+ clearInterval(timer);
377
+ // The ping path announces newly registered tools in its result text; this path
378
+ // must speak too. Without it the tools appear silently in the next system
379
+ // prompt while nothing in the conversation contradicts an earlier "Revit is
380
+ // not running" — the session's belief goes stale. Custom messages participate
381
+ // in LLM context; deliverAs "nextTurn" queues it for the next user prompt
382
+ // without interrupting or triggering anything.
383
+ try {
384
+ pi.sendMessage(
385
+ {
386
+ customType: "pi-revit",
387
+ content:
388
+ "Revit is now reachable: the Revit bridge tools (get_elements, set_parameters, execute_csharp, ...) were just registered in this session and are available from now on.",
389
+ display: true,
390
+ },
391
+ { deliverAs: "nextTurn" },
392
+ );
393
+ } catch {
394
+ // An older pi without sendMessage, or a torn-down session: the
395
+ // registration itself succeeded and must never be undone by the announcer.
396
+ }
376
397
  }, REDISCOVERY_INTERVAL_MS);
377
398
  timer.unref?.();
378
399
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-revit",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
4
4
  "description": "Native Pi connector for Autodesk Revit. Run npx.cmd -y pi-revit for the full Windows install.",
5
5
  "author": "Ahmad Altahlawi",
6
6
  "license": "MIT",
@@ -26,7 +26,8 @@
26
26
  "scripts": {
27
27
  "deploy": "powershell -ExecutionPolicy Bypass -File scripts/deploy.ps1",
28
28
  "setup": "powershell -ExecutionPolicy Bypass -File scripts/setup-workspace.ps1",
29
- "uninstall:revit": "powershell -ExecutionPolicy Bypass -File scripts/uninstall.ps1"
29
+ "uninstall:revit": "powershell -ExecutionPolicy Bypass -File scripts/uninstall.ps1",
30
+ "test:search": "dotnet run --project tests/search-engine"
30
31
  },
31
32
  "files": [
32
33
  "bin/",
@@ -31,7 +31,7 @@ Workflow guidance:
31
31
  - `get_elements` is the listing/counting primitive (`count_only: true` for bare counts). It returns identity fields only (id, name, category, typeName, levelId); read parameter values with `get_element_details`. Prefer a `category` or `of_class` scope when filtering by a parameter's display name.
32
32
  - The selection pipeline is `get_elements` -> ids -> `manage_selection` (action `set`); there is no inline filter on selection.
33
33
  - `set_parameters` is the home for bulk parameter writes AND renames (the `Name` parameter covers levels, views, sheets, types). One transaction per batch; per-element failures are reported. Pass `expected_document` (the model title) when several models are open or the session is long — it makes the write fail cleanly instead of landing in a different active document.
34
- - Parameter display names are LOCALIZED: in a non-English Revit UI, `Mark` is `Kennzeichen` (German), `マーク` (Japanese), etc. When a display-name lookup or `parameter_names` filter finds nothing, or the document may be non-English, use the language-independent `BuiltInParameter` enum name instead (e.g. `ALL_MODEL_MARK` for Mark, `ALL_MODEL_INSTANCE_COMMENTS` for Comments) — `set_parameters`, `get_element_details.parameter_names`, and `get_elements` filter rules all accept them, and `get_element_details` reports each parameter's `builtInParameter` name for discovery.
34
+ - Parameter display names are LOCALIZED: in a non-English Revit UI, `Mark`, `Comments`, and every other display name appear under their translated names. When a display-name lookup or `parameter_names` filter finds nothing, or the document may be non-English, use the language-independent `BuiltInParameter` enum name instead (e.g. `ALL_MODEL_MARK` for Mark, `ALL_MODEL_INSTANCE_COMMENTS` for Comments) — `set_parameters`, `get_element_details.parameter_names`, and `get_elements` filter rules all accept them, and `get_element_details` reports each parameter's `builtInParameter` name for discovery.
35
35
  - Before writing `execute_csharp` code, verify unfamiliar classes/members with `search_api_docs` (works with no document open; first query builds the index and takes a few seconds). The top match carries its remarks, parameter docs, and returns inline, and every public API enum value is searchable — trust the result over guessing or web search; narrow the query to promote a different match into the top slot.
36
36
  - `export_documents` files its output under `Documents\pi-revit\Models\<model title>\exports` automatically when `output_dir` is omitted — keyed to the exported document, so it lands right even across many models. Pass `output_dir` only when the user names a different target.
37
37
 
@@ -1,3 +1,4 @@
1
+ using Autodesk.Revit.DB;
1
2
  using Autodesk.Revit.UI;
2
3
  using RevitApplication = Autodesk.Revit.ApplicationServices.Application;
3
4
 
@@ -67,7 +68,32 @@ namespace RevitBridge
67
68
  {
68
69
  if (sender is RevitApplication app)
69
70
  _application = app;
70
- _hasOpenDocument = (_application?.Documents?.Size ?? 0) > 0;
71
+ try
72
+ {
73
+ // Linked documents count in Documents but are never the active UI
74
+ // document -- with only links loaded, ExternalEvents still are not
75
+ // pumped, so counting them would let a queued call hang for its full
76
+ // timeout instead of failing fast with the 409.
77
+ bool any = false;
78
+ var documents = _application?.Documents;
79
+ if (documents != null)
80
+ {
81
+ foreach (Document document in documents)
82
+ {
83
+ if (!document.IsLinked)
84
+ {
85
+ any = true;
86
+ break;
87
+ }
88
+ }
89
+ }
90
+ _hasOpenDocument = any;
91
+ }
92
+ catch
93
+ {
94
+ // Transitional states (mid-close) can make the iteration throw; keep
95
+ // the last known value -- the in-queue backstop still catches a miss.
96
+ }
71
97
  }
72
98
 
73
99
  private static string StartupErrorPath() =>
@@ -27,7 +27,7 @@ namespace RevitBridge.Tools
27
27
  {
28
28
  type = "array",
29
29
  items = new { type = "string" },
30
- description = "Only return these parameters. Matches the display name OR the BuiltInParameter enum name (case-insensitive exact). Display names are localized (e.g. 'Mark' is 'Kennzeichen' in a German UI) — prefer enum names like ALL_MODEL_MARK for language-independent filtering. Default: all.",
30
+ description = "Only return these parameters. Matches the display name OR the BuiltInParameter enum name (case-insensitive exact). Display names are localized in non-English Revit UIs — prefer enum names like ALL_MODEL_MARK for language-independent filtering. Default: all.",
31
31
  },
32
32
  include = new
33
33
  {