pi-revit 0.2.3 → 0.2.5

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 ADDED
@@ -0,0 +1,105 @@
1
+ # Changelog
2
+
3
+ All notable changes to pi-revit are documented here.
4
+ Format follows [Keep a Changelog](https://keepachangelog.com/); version headers use
5
+ `## [x.y.z] - YYYY-MM-DD` so tooling (and Pi's changelog parser format) can read them.
6
+
7
+ Every published version gets an entry with **Added** / **Changed** / **Fixed** sections
8
+ describing what the user will notice — not internal refactors.
9
+
10
+ ## [0.2.5] - 2026-07-20
11
+
12
+ ### Fixed
13
+ - `execute_csharp` dialog guard no longer answers every Revit popup with OK. On some
14
+ dialogs OK is the destructive choice (e.g. "Delete Element(s)"), so a script could
15
+ silently delete dimensions or constraints and still report success. Unrecognized
16
+ dialogs are now answered dismissively (Cancel, then Close, then No; OK only as the
17
+ last resort so Revit can never hang behind a popup), a small allowlist keeps OK for
18
+ dialogs that are safe to confirm, and `suppressedDialogs` now reports which answer
19
+ was given (e.g. `TaskDialog_… (answered Cancel)`).
20
+
21
+ ### Changed
22
+ - The `execute_csharp` tool description tells the model that confirmation prompts may be
23
+ cancelled and to check `suppressedDialogs` when a result looks incomplete.
24
+
25
+ Requires redeploying the Revit add-in (`scripts\deploy.ps1` + Revit restart) — `ping`
26
+ warns on a version mismatch until then.
27
+
28
+ ## [0.2.4] - 2026-07-20
29
+
30
+ ### Added
31
+ - This changelog. It ships inside the npm package and gets a `## [x.y.z]` entry with
32
+ **Added / Changed / Fixed** sections for every release, so updates report what actually
33
+ changed instead of just a version number.
34
+
35
+ ## [0.2.3] - 2026-07-20
36
+
37
+ ### Changed
38
+ - `search_api_docs`: results with the same short name in different namespaces are now
39
+ disambiguated with their full namespace, so `Category` vs internal schedule types
40
+ can't be confused.
41
+
42
+ ### Fixed
43
+ - Removed a hardcoded example from the overload note that could mislead the model into
44
+ copying a signature that didn't apply.
45
+
46
+ ## [0.2.2] - 2026-07-20
47
+
48
+ ### Added
49
+ - `search_api_docs`: exception documentation ("Throws:") is now shown for matched members.
50
+ - Overload-targeted queries: a query containing `(` matches against rendered signatures.
51
+
52
+ ### Changed
53
+ - Overloads now rank simplest-first (fewest parameters), so the common form appears on top.
54
+
55
+ ## [0.2.1] - 2026-07-16
56
+
57
+ ### Added
58
+ - Extension/add-in version handshake: `ping` reports both versions and warns when the
59
+ npm extension and the installed Revit add-in are out of sync (partial-update detection).
60
+
61
+ ## [0.2.0] - 2026-07-15
62
+
63
+ ### Changed
64
+ - SKILL.md: documents the top-match inline docs behaviour and the automatic
65
+ `Models\<title>\exports` output location so the agent uses them without prompting.
66
+
67
+ ## [0.1.9] - 2026-07-15
68
+
69
+ ### Added
70
+ - `search_api_docs` indexes every Revit API enum and surfaces `<remarks>` documentation.
71
+
72
+ ### Changed
73
+ - The top match's full documentation is placed directly in the tool's text output
74
+ (where model attention is strongest) instead of only in the structured payload.
75
+
76
+ ## [0.1.8] - 2026-07-13
77
+
78
+ ### Added
79
+ - Automatic per-model output sorting: exports, captures, and scripts land under
80
+ `Models\<model title>\` in the workspace, keyed to the source document.
81
+
82
+ ## [0.1.7] - 2026-07-13
83
+
84
+ ### Fixed
85
+ - npm-install uninstall flow no longer blocks itself on its own installation folder.
86
+
87
+ ## [0.1.6] - 2026-07-13
88
+
89
+ ### Changed
90
+ - The global launcher installs next to the user's permanent pi under npx.
91
+
92
+ ## [0.1.5] - 2026-07-13
93
+
94
+ ### Fixed
95
+ - Uninstall of the npm-installed Pi package.
96
+ - Workspace paths containing non-ASCII characters.
97
+
98
+ First version published to npm.
99
+
100
+ ## [0.1.0] - 2026-06-17
101
+
102
+ Initial public release: Revit bridge add-in (Revit 2025/2026/2027) plus Pi extension with
103
+ `ping`, `get_model_overview`, `get_elements`, `get_element_details`, `set_parameters`,
104
+ `manage_selection`, `capture_view`, `export_documents`, `execute_csharp`, and
105
+ `search_api_docs`.
package/package.json CHANGED
@@ -1,55 +1,56 @@
1
- {
2
- "name": "pi-revit",
3
- "version": "0.2.3",
4
- "description": "Native Pi connector for Autodesk Revit. Run npx.cmd -y pi-revit for the full Windows install.",
5
- "author": "Ahmad Altahlawi",
6
- "license": "MIT",
7
- "repository": {
8
- "type": "git",
9
- "url": "git+https://github.com/Triavision-ai/pi-revit.git"
10
- },
11
- "bugs": {
12
- "url": "https://github.com/Triavision-ai/pi-revit/issues"
13
- },
14
- "homepage": "https://github.com/Triavision-ai/pi-revit#readme",
15
- "keywords": [
16
- "pi-package",
17
- "pi-extension",
18
- "revit",
19
- "bim",
20
- "autodesk",
21
- "revit-api"
22
- ],
23
- "bin": {
24
- "pi-revit": "bin/pi-revit.js"
25
- },
26
- "scripts": {
27
- "deploy": "powershell -ExecutionPolicy Bypass -File scripts/deploy.ps1",
28
- "setup": "powershell -ExecutionPolicy Bypass -File scripts/setup-workspace.ps1",
29
- "uninstall:revit": "powershell -ExecutionPolicy Bypass -File scripts/uninstall.ps1"
30
- },
31
- "files": [
32
- "bin/",
33
- "extensions/",
34
- "skills/",
35
- "scripts/",
36
- "src/",
37
- "workspace/",
38
- "README.md"
39
- ],
40
- "pi": {
41
- "extensions": [
42
- "./extensions/pi-revit/index.ts"
43
- ],
44
- "skills": [
45
- "./skills"
46
- ]
47
- },
48
- "engines": {
49
- "node": ">=20.3"
50
- },
51
- "peerDependencies": {
52
- "@earendil-works/pi-coding-agent": "*",
53
- "typebox": "*"
54
- }
55
- }
1
+ {
2
+ "name": "pi-revit",
3
+ "version": "0.2.5",
4
+ "description": "Native Pi connector for Autodesk Revit. Run npx.cmd -y pi-revit for the full Windows install.",
5
+ "author": "Ahmad Altahlawi",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/Triavision-ai/pi-revit.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/Triavision-ai/pi-revit/issues"
13
+ },
14
+ "homepage": "https://github.com/Triavision-ai/pi-revit#readme",
15
+ "keywords": [
16
+ "pi-package",
17
+ "pi-extension",
18
+ "revit",
19
+ "bim",
20
+ "autodesk",
21
+ "revit-api"
22
+ ],
23
+ "bin": {
24
+ "pi-revit": "bin/pi-revit.js"
25
+ },
26
+ "scripts": {
27
+ "deploy": "powershell -ExecutionPolicy Bypass -File scripts/deploy.ps1",
28
+ "setup": "powershell -ExecutionPolicy Bypass -File scripts/setup-workspace.ps1",
29
+ "uninstall:revit": "powershell -ExecutionPolicy Bypass -File scripts/uninstall.ps1"
30
+ },
31
+ "files": [
32
+ "bin/",
33
+ "extensions/",
34
+ "skills/",
35
+ "scripts/",
36
+ "src/",
37
+ "workspace/",
38
+ "README.md",
39
+ "CHANGELOG.md"
40
+ ],
41
+ "pi": {
42
+ "extensions": [
43
+ "./extensions/pi-revit/index.ts"
44
+ ],
45
+ "skills": [
46
+ "./skills"
47
+ ]
48
+ },
49
+ "engines": {
50
+ "node": ">=20.3"
51
+ },
52
+ "peerDependencies": {
53
+ "@earendil-works/pi-coding-agent": "*",
54
+ "typebox": "*"
55
+ }
56
+ }
@@ -59,7 +59,7 @@ namespace RevitBridge.Tools
59
59
 
60
60
  public string Name => "execute_csharp";
61
61
  public string Label => "Execute C#";
62
- public string Description => "Compile and run a C# script on the Revit API thread against the open model — the escape hatch for anything without a dedicated tool: element creation, deletion, geometry edits (move/copy/rotate), views, sheets, schedules, tagging, families, links, worksets. Globals: doc (Document), uidoc (UIDocument), uiapp (UIApplication), and Dump(value) to record intermediate values into the result's dumps[]. Default imports: System, System.Linq, System.Collections.Generic, Autodesk.Revit.DB, Autodesk.Revit.UI — add using directives at the top for sub-namespaces (e.g. using Autodesk.Revit.DB.Architecture;). The entire run is wrapped in ONE transaction named 'execute_csharp': committed on success, rolled back on any exception, so a failed script never changes the model (do not open your own Transaction; sub-transactions are fine). The script's final expression or return statement becomes returnValue; return primitives, strings, or anonymous objects/lists — Revit API values are projected to safe shapes (Element -> {id,name,category,typeName,levelId}, ElementId -> number, XYZ -> {x,y,z}, Parameter -> {name,value,displayValue}; other API objects become strings) with depth and item caps, so never rely on raw API objects round-tripping. Lengths are in internal units (decimal feet) — convert with UnitUtils. Prefer collector-level filtering (FilteredElementCollector .OfCategory/.OfClass/.WhereElementIsNotElementType) and bounded loops: the call budget is 120s and Revit cannot be interrupted mid-script. Scripts must be fully synchronous — await/async is rejected at compile time, and blocking on tasks (Task.Result/.Wait()) can freeze Revit. Modal dialogs raised while running are auto-dismissed and reported in suppressedDialogs. Verify unfamiliar signatures with search_api_docs first.";
62
+ public string Description => "Compile and run a C# script on the Revit API thread against the open model — the escape hatch for anything without a dedicated tool: element creation, deletion, geometry edits (move/copy/rotate), views, sheets, schedules, tagging, families, links, worksets. Globals: doc (Document), uidoc (UIDocument), uiapp (UIApplication), and Dump(value) to record intermediate values into the result's dumps[]. Default imports: System, System.Linq, System.Collections.Generic, Autodesk.Revit.DB, Autodesk.Revit.UI — add using directives at the top for sub-namespaces (e.g. using Autodesk.Revit.DB.Architecture;). The entire run is wrapped in ONE transaction named 'execute_csharp': committed on success, rolled back on any exception, so a failed script never changes the model (do not open your own Transaction; sub-transactions are fine). The script's final expression or return statement becomes returnValue; return primitives, strings, or anonymous objects/lists — Revit API values are projected to safe shapes (Element -> {id,name,category,typeName,levelId}, ElementId -> number, XYZ -> {x,y,z}, Parameter -> {name,value,displayValue}; other API objects become strings) with depth and item caps, so never rely on raw API objects round-tripping. Lengths are in internal units (decimal feet) — convert with UnitUtils. Prefer collector-level filtering (FilteredElementCollector .OfCategory/.OfClass/.WhereElementIsNotElementType) and bounded loops: the call budget is 120s and Revit cannot be interrupted mid-script. Scripts must be fully synchronous — await/async is rejected at compile time, and blocking on tasks (Task.Result/.Wait()) can freeze Revit. Modal dialogs raised while running are auto-dismissed and reported in suppressedDialogs — unrecognized dialogs are answered dismissively (Cancel/Close/No) rather than confirmed, so an operation that raises a confirmation prompt may be cancelled; check suppressedDialogs when a result looks incomplete. Verify unfamiliar signatures with search_api_docs first.";
63
63
  public bool Write => true;
64
64
 
65
65
  public object ParametersSchema => new
@@ -234,9 +234,31 @@ namespace RevitBridge.Tools
234
234
  }
235
235
 
236
236
  /// <summary>Auto-dismisses any modal Revit dialog raised while the script runs, so a
237
- /// popup cannot hang the Revit thread; dismissed dialog ids are reported.</summary>
237
+ /// popup cannot hang the Revit thread; dismissed dialog ids and the answer given are
238
+ /// reported. Unrecognized dialogs get the dismissive answer (Cancel, then Close, then
239
+ /// No) — on several Revit dialogs OK is the destructive choice (e.g. "Delete
240
+ /// Element(s)"), so confirming blind can silently damage the model. OK leads only for
241
+ /// dialogs known to be safe to confirm, and is otherwise the last resort: every
242
+ /// override attempt failing would leave the dialog up and hang the Revit thread,
243
+ /// which is the one outcome this guard exists to prevent.</summary>
238
244
  private sealed class DialogGuard : IDisposable
239
245
  {
246
+ private const int IDOK = 1;
247
+ private const int IDCANCEL = 2;
248
+ private const int IDNO = 7;
249
+ private const int IDCLOSE = 8;
250
+
251
+ /// <summary>Dialogs where confirming is the benign answer and cancelling would
252
+ /// abort the operation the script deliberately started.</summary>
253
+ private static readonly HashSet<string> ConfirmSafeDialogIds = new(StringComparer.OrdinalIgnoreCase)
254
+ {
255
+ // "Export with temporary hide/isolate": OK exports the view as displayed.
256
+ "TaskDialog_Really_Print_Or_Export_Temp_View_Modes",
257
+ };
258
+
259
+ private static readonly int[] ConfirmFirst = { IDOK, IDCANCEL, IDCLOSE };
260
+ private static readonly int[] DismissFirst = { IDCANCEL, IDCLOSE, IDNO, IDOK };
261
+
240
262
  private readonly UIApplication _uiapp;
241
263
  public List<string> Suppressed { get; } = new();
242
264
 
@@ -248,17 +270,35 @@ namespace RevitBridge.Tools
248
270
 
249
271
  private void OnDialogBoxShowing(object? sender, DialogBoxShowingEventArgs e)
250
272
  {
251
- Suppressed.Add(string.IsNullOrEmpty(e.DialogId) ? e.GetType().Name : e.DialogId);
252
- try
253
- {
254
- e.OverrideResult(1); // IDOK
255
- }
256
- catch
273
+ string id = string.IsNullOrEmpty(e.DialogId) ? e.GetType().Name : e.DialogId;
274
+ int[] answers = ConfirmSafeDialogIds.Contains(id) ? ConfirmFirst : DismissFirst;
275
+ foreach (int answer in answers)
257
276
  {
258
- // Some dialogs reject overrides; never let the guard itself throw.
277
+ try
278
+ {
279
+ if (e.OverrideResult(answer))
280
+ {
281
+ Suppressed.Add($"{id} (answered {AnswerName(answer)})");
282
+ return;
283
+ }
284
+ }
285
+ catch
286
+ {
287
+ // Some dialogs reject specific overrides; try the next answer.
288
+ }
259
289
  }
290
+ Suppressed.Add($"{id} (override rejected — dialog may need manual dismissal)");
260
291
  }
261
292
 
293
+ private static string AnswerName(int answer) => answer switch
294
+ {
295
+ IDOK => "OK",
296
+ IDCANCEL => "Cancel",
297
+ IDNO => "No",
298
+ IDCLOSE => "Close",
299
+ _ => answer.ToString(),
300
+ };
301
+
262
302
  public void Dispose()
263
303
  {
264
304
  try