pi-revit 0.2.5 → 0.2.6

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,22 @@ 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.6] - 2026-07-20
11
+
12
+ ### Fixed
13
+ - Write transactions (`set_parameters`, `execute_csharp`, and the temporary-isolate
14
+ branch of `manage_selection`) now register a failures preprocessor. Previously Revit
15
+ handled commit failures interactively: warnings popped the transient toast and spammed
16
+ the journal, and an error-severity failure showed the modal resolution dialog, blocking
17
+ the bridge until a human clicked. Now warnings are auto-dismissed and reported back
18
+ (`commitWarnings` in the result, e.g. duplicate Mark values), and errors roll the
19
+ transaction back with the actual Revit failure text in the error message.
20
+
21
+ ### Changed
22
+ - `set_parameters` tool description tells the model to relay `commitWarnings` to the user.
23
+
24
+ Requires redeploying the Revit add-in (`scripts\deploy.ps1` + Revit restart).
25
+
10
26
  ## [0.2.5] - 2026-07-20
11
27
 
12
28
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-revit",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
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",
@@ -113,6 +113,7 @@ namespace RevitBridge.Tools
113
113
 
114
114
  using var dialogGuard = new DialogGuard(uiapp);
115
115
  using var transaction = new Transaction(doc, "execute_csharp");
116
+ var failureGuard = FailureGuard.Attach(transaction);
116
117
  if (transaction.Start() != TransactionStatus.Started)
117
118
  throw new InvalidOperationException("Unable to start the execute_csharp transaction.");
118
119
 
@@ -142,6 +143,7 @@ namespace RevitBridge.Tools
142
143
  if (transaction.Commit() != TransactionStatus.Committed)
143
144
  throw new InvalidOperationException(
144
145
  "Revit rolled back the execute_csharp transaction during commit (failure processing rejected the changes); no model changes were saved."
146
+ + failureGuard.DescribeErrors()
145
147
  + DescribeDialogs(dialogGuard.Suppressed));
146
148
 
147
149
  stopwatch.Stop();
@@ -154,6 +156,8 @@ namespace RevitBridge.Tools
154
156
  };
155
157
  if (dialogGuard.Suppressed.Count > 0)
156
158
  payload["suppressedDialogs"] = dialogGuard.Suppressed;
159
+ if (failureGuard.Warnings.Count > 0)
160
+ payload["commitWarnings"] = failureGuard.Warnings;
157
161
  return payload;
158
162
  }
159
163
 
@@ -0,0 +1,62 @@
1
+ using Autodesk.Revit.DB;
2
+
3
+ namespace RevitBridge.Tools
4
+ {
5
+ /// <summary>
6
+ /// Deterministic commit-time failure handling for tool-owned transactions. Without a
7
+ /// preprocessor, Revit resolves commit failures interactively: warnings pop the
8
+ /// transient toast (and spam the journal), and error-severity failures block the
9
+ /// Revit API thread behind the modal resolution dialog until a human clicks — past
10
+ /// the bridge's call budget. Attach() deletes warnings (recorded for the tool
11
+ /// result) and turns errors into a rollback, so a headless caller always gets an
12
+ /// answer instead of a hang.
13
+ /// </summary>
14
+ internal sealed class FailureGuard : IFailuresPreprocessor
15
+ {
16
+ public List<string> Warnings { get; } = new();
17
+ public List<string> Errors { get; } = new();
18
+
19
+ public static FailureGuard Attach(Transaction transaction)
20
+ {
21
+ var guard = new FailureGuard();
22
+ var options = transaction.GetFailureHandlingOptions();
23
+ options.SetFailuresPreprocessor(guard);
24
+ options.SetClearAfterRollback(true);
25
+ transaction.SetFailureHandlingOptions(options);
26
+ return guard;
27
+ }
28
+
29
+ public FailureProcessingResult PreprocessFailures(FailuresAccessor accessor)
30
+ {
31
+ bool hasError = false;
32
+ foreach (FailureMessageAccessor failure in accessor.GetFailureMessages())
33
+ {
34
+ string description;
35
+ try
36
+ {
37
+ description = failure.GetDescriptionText();
38
+ }
39
+ catch
40
+ {
41
+ description = "(failure without description)";
42
+ }
43
+
44
+ if (failure.GetSeverity() == FailureSeverity.Warning)
45
+ {
46
+ Warnings.Add(description);
47
+ accessor.DeleteWarning(failure);
48
+ }
49
+ else
50
+ {
51
+ hasError = true;
52
+ Errors.Add(description);
53
+ }
54
+ }
55
+ return hasError ? FailureProcessingResult.ProceedWithRollBack : FailureProcessingResult.Continue;
56
+ }
57
+
58
+ /// <summary>Formats the recorded errors for a commit-failure message.</summary>
59
+ public string DescribeErrors()
60
+ => Errors.Count > 0 ? $" Revit failure(s): {string.Join("; ", Errors)}." : string.Empty;
61
+ }
62
+ }
@@ -192,6 +192,7 @@ namespace RevitBridge.Tools
192
192
  private static void ApplyTemporaryIsolate(Document doc, View view, ICollection<ElementId> elementIds)
193
193
  {
194
194
  using var transaction = new Transaction(doc, "manage_selection: temporary isolate");
195
+ var failureGuard = FailureGuard.Attach(transaction);
195
196
  if (transaction.Start() != TransactionStatus.Started)
196
197
  throw new InvalidOperationException("Unable to start the temporary-isolate transaction.");
197
198
  try
@@ -201,7 +202,7 @@ namespace RevitBridge.Tools
201
202
  else
202
203
  view.IsolateElementsTemporary(elementIds);
203
204
  if (transaction.Commit() != TransactionStatus.Committed)
204
- throw new InvalidOperationException("The temporary-isolate transaction failed to commit.");
205
+ throw new InvalidOperationException("The temporary-isolate transaction failed to commit." + failureGuard.DescribeErrors());
205
206
  }
206
207
  catch (Autodesk.Revit.Exceptions.InvalidOperationException ex)
207
208
  {
@@ -19,7 +19,7 @@ namespace RevitBridge.Tools
19
19
 
20
20
  public string Name => "set_parameters";
21
21
  public string Label => "Set Parameters";
22
- public string Description => "Write parameter values on elements — also the home for rename: parameter 'Name' covers levels, views, sheets, types, etc. (falls back to the element's Name property when the Name parameter is read-only). updates apply in ONE transaction: partial success commits and lists the failures; if every update fails the transaction is rolled back and nothing changes. parameter accepts a display name (Comments, Mark, Name), a BuiltInParameter enum name (e.g. ALL_MODEL_MARK), or guid:<GUID> for a shared parameter; type parameters live on the element type, so pass the type's id. Values are validated against the parameter's storage type; numeric values are interpreted in the document's display units for that parameter unless 'unit' (e.g. millimeters, feet, squareMeters) is given.";
22
+ public string Description => "Write parameter values on elements — also the home for rename: parameter 'Name' covers levels, views, sheets, types, etc. (falls back to the element's Name property when the Name parameter is read-only). updates apply in ONE transaction: partial success commits and lists the failures; if every update fails the transaction is rolled back and nothing changes. parameter accepts a display name (Comments, Mark, Name), a BuiltInParameter enum name (e.g. ALL_MODEL_MARK), or guid:<GUID> for a shared parameter; type parameters live on the element type, so pass the type's id. Values are validated against the parameter's storage type; numeric values are interpreted in the document's display units for that parameter unless 'unit' (e.g. millimeters, feet, squareMeters) is given. Revit warnings raised at commit (e.g. duplicate Mark values) are auto-dismissed and listed in commitWarnings — mention them to the user; error-severity failures roll the whole transaction back.";
23
23
  public bool Write => true;
24
24
 
25
25
  public object ParametersSchema => new
@@ -64,6 +64,7 @@ namespace RevitBridge.Tools
64
64
  var failed = new List<Dictionary<string, object?>>();
65
65
 
66
66
  using var transaction = new Transaction(doc, "set_parameters");
67
+ var failureGuard = FailureGuard.Attach(transaction);
67
68
  if (transaction.Start() != TransactionStatus.Started)
68
69
  throw new InvalidOperationException("Unable to start the set_parameters transaction.");
69
70
 
@@ -95,7 +96,9 @@ namespace RevitBridge.Tools
95
96
  if (succeeded.Count > 0)
96
97
  {
97
98
  if (transaction.Commit() != TransactionStatus.Committed)
98
- throw new InvalidOperationException("The set_parameters transaction failed to commit; no changes were saved.");
99
+ throw new InvalidOperationException(
100
+ "Revit rejected the set_parameters commit and the transaction was rolled back; no changes were saved."
101
+ + failureGuard.DescribeErrors());
99
102
  }
100
103
  else
101
104
  {
@@ -118,6 +121,8 @@ namespace RevitBridge.Tools
118
121
  : succeeded.Count == 0
119
122
  ? $"No updates applied; all {failed.Count} failed — transaction rolled back.{failureSample}"
120
123
  : $"Updated {succeeded.Count} parameter value(s) on {elementCount} element(s); {failed.Count} failed.{failureSample}";
124
+ if (failureGuard.Warnings.Count > 0)
125
+ compact += $" {failureGuard.Warnings.Count} Revit warning(s) auto-dismissed at commit (see commitWarnings), e.g.: {failureGuard.Warnings[0]}";
121
126
 
122
127
  return new ToolOutput(new
123
128
  {
@@ -125,6 +130,7 @@ namespace RevitBridge.Tools
125
130
  committed = succeeded.Count > 0,
126
131
  succeeded,
127
132
  failed,
133
+ commitWarnings = failureGuard.Warnings,
128
134
  }, compact);
129
135
  }
130
136