pi-revit 0.1.9 → 0.2.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/extensions/pi-revit/index.ts +27 -1
- package/package.json +1 -1
- package/scripts/build.ps1 +11 -0
- package/skills/pi-revit/SKILL.md +2 -1
- package/src/Revit/BridgeServer.cs +11 -1
|
@@ -3,6 +3,7 @@ import { Type, type TSchema } from "typebox";
|
|
|
3
3
|
import { readFile } from "node:fs/promises";
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
|
+
import { version as packageVersion } from "../../package.json";
|
|
6
7
|
|
|
7
8
|
interface BridgeInfo {
|
|
8
9
|
baseUrl: string;
|
|
@@ -195,6 +196,17 @@ function registerBridgeTool(pi: ExtensionAPI, descriptor: BridgeToolDescriptor)
|
|
|
195
196
|
});
|
|
196
197
|
}
|
|
197
198
|
|
|
199
|
+
/** `pi update --extensions` refreshes this package but not the deployed Revit add-in,
|
|
200
|
+
* so a newer extension can silently talk to an older bridge. The add-in reports the
|
|
201
|
+
* package version it was built from (stamped by scripts/build.ps1); any difference
|
|
202
|
+
* means the update is incomplete. */
|
|
203
|
+
function versionMismatch(addinVersion: unknown): string | null {
|
|
204
|
+
const addin = typeof addinVersion === "string" && addinVersion.length > 0 ? addinVersion : null;
|
|
205
|
+
if (addin === packageVersion) return null;
|
|
206
|
+
const state = addin ? `still runs version ${addin}` : "predates version reporting";
|
|
207
|
+
return `pi-revit ${packageVersion} is installed, but the Revit add-in ${state} — the update is incomplete. Close Revit and run: npx.cmd -y pi-revit (or ask the agent to run scripts\\deploy.ps1 from the installed package, then restart Revit).`;
|
|
208
|
+
}
|
|
209
|
+
|
|
198
210
|
function registerPing(pi: ExtensionAPI) {
|
|
199
211
|
pi.registerTool({
|
|
200
212
|
name: "ping",
|
|
@@ -206,8 +218,9 @@ function registerPing(pi: ExtensionAPI) {
|
|
|
206
218
|
executionMode: "sequential",
|
|
207
219
|
async execute(_toolCallId, _params, signal) {
|
|
208
220
|
const payload = await bridgeRequest("/ping", { method: "GET" }, signal, 10_000);
|
|
221
|
+
const warning = versionMismatch((payload as { addinVersion?: string }).addinVersion);
|
|
209
222
|
return {
|
|
210
|
-
content: [{ type: "text", text: JSON.stringify(payload) }],
|
|
223
|
+
content: [{ type: "text", text: JSON.stringify(payload) + (warning ? `\nWARNING: ${warning}` : "") }],
|
|
211
224
|
details: payload,
|
|
212
225
|
};
|
|
213
226
|
},
|
|
@@ -219,6 +232,19 @@ export default async function revitConnector(pi: ExtensionAPI) {
|
|
|
219
232
|
// bridge is down, so it is never part of /tools discovery.
|
|
220
233
|
registerPing(pi);
|
|
221
234
|
|
|
235
|
+
// Surface an incomplete update (see versionMismatch) once per session, right
|
|
236
|
+
// where the user lands after running `pi update --extensions`. Bridge down at
|
|
237
|
+
// session start is the normal Revit-closed case: stay quiet.
|
|
238
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
239
|
+
try {
|
|
240
|
+
const payload = (await bridgeRequest("/ping", { method: "GET" }, undefined, 3_000)) as { addinVersion?: string };
|
|
241
|
+
const warning = versionMismatch(payload.addinVersion);
|
|
242
|
+
if (warning) ctx.ui.notify(warning, "warning");
|
|
243
|
+
} catch {
|
|
244
|
+
// No bridge, no verdict.
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
|
|
222
248
|
let descriptors: BridgeToolDescriptor[];
|
|
223
249
|
try {
|
|
224
250
|
const payload = (await bridgeRequest("/tools", { method: "GET" }, undefined, DISCOVERY_TIMEOUT_MS)) as {
|
package/package.json
CHANGED
package/scripts/build.ps1
CHANGED
|
@@ -20,6 +20,17 @@ $ErrorActionPreference = 'Stop'
|
|
|
20
20
|
$project = Join-Path $PSScriptRoot '..\src\Revit\RevitBridge.csproj'
|
|
21
21
|
|
|
22
22
|
$buildArgs = @('build', $project, '-c', $Configuration)
|
|
23
|
+
|
|
24
|
+
# Stamp the package version into the assembly so the bridge can report which release
|
|
25
|
+
# the deployed add-in came from; the pi extension compares it against its own package
|
|
26
|
+
# version at session start to detect partial updates.
|
|
27
|
+
$packageJson = Join-Path $PSScriptRoot '..\package.json'
|
|
28
|
+
if (Test-Path $packageJson) {
|
|
29
|
+
$packageVersion = (Get-Content $packageJson -Raw | ConvertFrom-Json).version
|
|
30
|
+
if ($packageVersion) {
|
|
31
|
+
$buildArgs += "-p:Version=$packageVersion"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
23
34
|
if ($TargetFramework) {
|
|
24
35
|
# Override TargetFrameworks (plural) rather than TargetFramework: NuGet restore ignores a
|
|
25
36
|
# single -p:TargetFramework and still restores every framework the project declares, so a
|
package/skills/pi-revit/SKILL.md
CHANGED
|
@@ -30,7 +30,8 @@ Workflow guidance:
|
|
|
30
30
|
- `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.
|
|
31
31
|
- The selection pipeline is `get_elements` -> ids -> `manage_selection` (action `set`); there is no inline filter on selection.
|
|
32
32
|
- `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.
|
|
33
|
-
- 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).
|
|
33
|
+
- 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.
|
|
34
|
+
- `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.
|
|
34
35
|
|
|
35
36
|
## execute_csharp playbook
|
|
36
37
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
using System.IO;
|
|
2
2
|
using System.Net;
|
|
3
3
|
using System.Net.Sockets;
|
|
4
|
+
using System.Reflection;
|
|
4
5
|
using System.Text;
|
|
5
6
|
using System.Text.Json;
|
|
6
7
|
|
|
@@ -22,6 +23,15 @@ namespace RevitBridge
|
|
|
22
23
|
{
|
|
23
24
|
private const int DefaultPort = 47777;
|
|
24
25
|
private const int MaxPort = 47797;
|
|
26
|
+
|
|
27
|
+
/// <summary>Package version stamped into the assembly by scripts/build.ps1. The pi
|
|
28
|
+
/// extension compares this against its own package version to detect partial
|
|
29
|
+
/// updates (npm package updated, add-in not redeployed); a build made without
|
|
30
|
+
/// the stamp reports its default assembly version instead.</summary>
|
|
31
|
+
private static readonly string AddinVersion =
|
|
32
|
+
typeof(BridgeServer).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion?.Split('+')[0]
|
|
33
|
+
?? typeof(BridgeServer).Assembly.GetName().Version?.ToString(3)
|
|
34
|
+
?? "unknown";
|
|
25
35
|
private const int MaxRequestBytes = 4_000_000;
|
|
26
36
|
private const int MaxContentChars = 12_000;
|
|
27
37
|
|
|
@@ -260,7 +270,7 @@ namespace RevitBridge
|
|
|
260
270
|
private async Task<(int Status, object Response)> RouteAsync(string method, string path, Dictionary<string, string> query, string body, CancellationToken token)
|
|
261
271
|
{
|
|
262
272
|
if (method == "GET" && path == "/ping")
|
|
263
|
-
return (200, new { ok = true, service = "revit-bridge", revitVersion = _revitVersion, pid = Environment.ProcessId });
|
|
273
|
+
return (200, new { ok = true, service = "revit-bridge", revitVersion = _revitVersion, pid = Environment.ProcessId, addinVersion = AddinVersion });
|
|
264
274
|
|
|
265
275
|
if (method == "GET" && path == "/tools")
|
|
266
276
|
{
|