pi-revit 0.1.7 → 0.1.8

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/README.md CHANGED
@@ -115,16 +115,16 @@ That's all. Pi starts with the Revit tools ready:
115
115
  `pi` command itself. That folder is on your system PATH — which is exactly why *every* terminal
116
116
  finds `pi-revit`, with no extra configuration. When you run it, it switches to your workspace at
117
117
  `Documents\pi-revit` and starts Pi there, so your conventions file (`AGENTS.md`) loads
118
- automatically and all Revit session history lives in one predictable place. The Revit tools
119
- themselves are installed globally in Pi, and the extension discovers them live from the bridge
120
- inside Revit each time a session starts.
118
+ automatically and all Revit session history lives in one predictable place (`pi-revit -c`
119
+ continues the last session). The Revit tools themselves are installed globally in Pi, and the
120
+ extension discovers them live from the bridge inside Revit each time a session starts.
121
121
 
122
- **Per project:** create one subfolder per Revit project under `Documents\pi-revit\Projects\`:
123
-
124
- ```powershell
125
- pi-revit tower-b # Pi scoped to that project — its notes and its session history
126
- pi-revit tower-b -c # continue that project's last session
127
- ```
122
+ **Per model, automatically:** files sort themselves. Exports land in
123
+ `Documents\pi-revit\Models\<model title>\exports` — the add-in derives the folder from the
124
+ document being exported, so even a session that touches many models files every output under
125
+ the right one, with no naming decision from you or the AI. Each model folder carries a
126
+ `model.txt` recording the model's GUID and file path, so two models that share a title stay
127
+ distinguishable.
128
128
 
129
129
  Plain `pi` from any folder also works; `pi-revit` just adds the right working folder on top.
130
130
 
@@ -142,7 +142,7 @@ Plain `pi` from any folder also works; `pi-revit` just adds the right working fo
142
142
  | `search_api_docs` | Search the offline Revit API docs (works with no document open) |
143
143
  | `execute_csharp` | Run a C# script in one auto-managed transaction — the escape hatch |
144
144
  | `capture_view` | PNG snapshot of a view to a temp file (read the returned path to see it) |
145
- | `export_documents` | PDF/DWG/PNG/IFC export of sheets and views |
145
+ | `export_documents` | PDF/DWG/PNG/IFC export of sheets and views — auto-sorted into `Models\<model>\exports` |
146
146
  | `get_model_health` | Warnings grouped + worksets, phases, design options audit |
147
147
 
148
148
  ## Limitations — read before using on real projects
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-revit",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
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",
@@ -2,12 +2,13 @@
2
2
  <#
3
3
  Sets up the pi-revit user environment on this PC:
4
4
 
5
- 1. Workspace at Documents\pi-revit (AGENTS.md conventions, Projects\sample template,
6
- double-click launcher). Existing AGENTS.md files are never overwritten.
5
+ 1. Workspace at Documents\pi-revit (AGENTS.md conventions, Models\ output tree,
6
+ double-click launcher). An existing AGENTS.md is never overwritten.
7
7
  2. Global `pi-revit` command installed next to the `pi` command, so any terminal can run:
8
8
  pi-revit -> Pi in the workspace
9
- pi-revit <project> -> Pi in Projects\<project>
10
- pi-revit <project> -c -> continue that project's last session
9
+ pi-revit -c -> continue the last session
10
+ Model output sorts itself: the Revit tools file each export under
11
+ Models\<model title>\ automatically, keyed by the document it came from.
11
12
 
12
13
  Idempotent — safe to re-run. Usage:
13
14
  scripts\setup-workspace.ps1
@@ -20,18 +21,14 @@ param(
20
21
  $ErrorActionPreference = 'Stop'
21
22
  $templates = Join-Path (Split-Path $PSScriptRoot -Parent) 'workspace'
22
23
 
23
- # 1. Workspace folders
24
- New-Item -ItemType Directory -Force -Path (Join-Path $WorkspaceDir 'Projects\sample') | Out-Null
24
+ # 1. Workspace folders. Models\ is where the Revit tools file per-model output.
25
+ New-Item -ItemType Directory -Force -Path (Join-Path $WorkspaceDir 'Models') | Out-Null
25
26
 
26
27
  # Conventions / notes: copy only when missing so user edits survive re-runs.
27
28
  $workspaceAgents = Join-Path $WorkspaceDir 'AGENTS.md'
28
29
  if (-not (Test-Path $workspaceAgents)) {
29
30
  Copy-Item (Join-Path $templates 'AGENTS.md') $workspaceAgents
30
31
  }
31
- $projectAgents = Join-Path $WorkspaceDir 'Projects\sample\AGENTS.md'
32
- if (-not (Test-Path $projectAgents)) {
33
- Copy-Item (Join-Path $templates 'project-AGENTS.md') $projectAgents
34
- }
35
32
 
36
33
  # Launcher is code, not user data: always refresh.
37
34
  Copy-Item (Join-Path $templates 'pi-revit-here.cmd') (Join-Path $WorkspaceDir 'pi-revit.cmd') -Force
@@ -77,7 +74,7 @@ if ($pi) {
77
74
  # localized folder names) stay intact.
78
75
  Set-Content -Path (Join-Path $binDir 'pi-revit.cmd') -Value $globalCmd -Encoding Oem
79
76
  Write-Host "Global command installed: $(Join-Path $binDir 'pi-revit.cmd')" -ForegroundColor Green
80
- Write-Host 'Run pi-revit from any terminal (pi-revit <project> for a project folder).'
77
+ Write-Host 'Run pi-revit from any terminal (pi-revit -c continues the last session).'
81
78
  } else {
82
79
  Write-Warning 'No permanent pi command found on PATH. Install Pi first (npm install -g --ignore-scripts @earendil-works/pi-coding-agent), then run npx.cmd -y pi-revit again (or re-run this script) to get the global pi-revit command.'
83
80
  }
@@ -19,7 +19,7 @@ namespace RevitBridge.Tools
19
19
 
20
20
  public string Name => "export_documents";
21
21
  public string Label => "Export Documents";
22
- public string Description => "Export documents from the open Revit model. format 'pdf'/'dwg'/'png' export the given sheet/view ids to files: pdf combines everything into one file by default (combine=false writes one PDF per sheet/view, named by Revit's naming rule); png renders 2048 px wide; ifc exports the whole model, or just what one given view shows. Files land in output_dir (created if missing; default: a fresh folder under the system temp directory); file_name_prefix sets the base file name (default: the document title; Revit appends view/sheet suffixes for multi-file exports). Returns the produced file paths with sizes. Find sheet/view ids with get_elements (category 'Sheets' or 'Views') first.";
22
+ public string Description => "Export documents from the open Revit model. format 'pdf'/'dwg'/'png' export the given sheet/view ids to files: pdf combines everything into one file by default (combine=false writes one PDF per sheet/view, named by Revit's naming rule); png renders 2048 px wide; ifc exports the whole model, or just what one given view shows. Files sort themselves per model: with output_dir omitted they land in Documents\\pi-revit\\Models\\<model title>\\exports, derived from the document being exported (pass output_dir only for a different explicit target); file_name_prefix sets the base file name (default: the document title; Revit appends view/sheet suffixes for multi-file exports). Returns the produced file paths with sizes. Find sheet/view ids with get_elements (category 'Sheets' or 'Views') first.";
23
23
  public bool Write => true;
24
24
  public string Tier => "advanced";
25
25
 
@@ -43,7 +43,7 @@ namespace RevitBridge.Tools
43
43
  output_dir = new
44
44
  {
45
45
  type = "string",
46
- description = "Output directory, created if missing. Default: a fresh folder under the system temp directory.",
46
+ description = "Output directory, created if missing. Default: Documents\\pi-revit\\Models\\<model title>\\exports — files sort under the exported model automatically; omit unless the user names a different target.",
47
47
  },
48
48
  file_name_prefix = new
49
49
  {
@@ -74,7 +74,7 @@ namespace RevitBridge.Tools
74
74
  throw new ArgumentException($"Unknown format: {JsonArgs.GetString(args, "format")}. Supported: pdf, dwg, png, ifc.");
75
75
 
76
76
  var views = ResolveViews(doc, args, format);
77
- string outputDir = ResolveOutputDir(args);
77
+ string outputDir = ResolveOutputDir(args, doc);
78
78
  string? prefixInput = JsonArgs.GetString(args, "file_name_prefix");
79
79
  string baseName = SanitizeFileName(string.IsNullOrWhiteSpace(prefixInput) ? doc.Title : prefixInput.Trim());
80
80
  bool combine = JsonArgs.GetBool(args, "combine", true);
@@ -236,16 +236,48 @@ namespace RevitBridge.Tools
236
236
  return views;
237
237
  }
238
238
 
239
- private static string ResolveOutputDir(JsonElement args)
239
+ private static string ResolveOutputDir(JsonElement args, Document doc)
240
240
  {
241
241
  string? requested = JsonArgs.GetString(args, "output_dir");
242
242
  string outputDir = string.IsNullOrWhiteSpace(requested)
243
- ? Path.Combine(Path.GetTempPath(), "revit_export_" + Guid.NewGuid().ToString("N"))
243
+ ? Path.Combine(ModelFolder(doc), "exports")
244
244
  : Path.GetFullPath(requested.Trim());
245
245
  Directory.CreateDirectory(outputDir);
246
246
  return outputDir;
247
247
  }
248
248
 
249
+ /// <summary>Per-model folder under the pi-revit workspace:
250
+ /// Documents\pi-revit\Models\&lt;model title&gt;. The exporting tool is the one
251
+ /// component that knows with certainty which model a file belongs to, so the
252
+ /// sorting is automatic — never an agent or user decision. model.txt records
253
+ /// the model's identity so same-titled models stay distinguishable.</summary>
254
+ private static string ModelFolder(Document doc)
255
+ {
256
+ string workspace = Path.Combine(
257
+ Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "pi-revit");
258
+ string title = SanitizeFileName(string.IsNullOrWhiteSpace(doc.Title) ? "untitled" : doc.Title);
259
+ string folder = Path.Combine(workspace, "Models", title);
260
+ Directory.CreateDirectory(folder);
261
+ TryRecordModelIdentity(folder, doc);
262
+ return folder;
263
+ }
264
+
265
+ private static void TryRecordModelIdentity(string folder, Document doc)
266
+ {
267
+ try
268
+ {
269
+ string guid = doc.ProjectInformation?.UniqueId ?? string.Empty;
270
+ string line = $"{guid}\t{doc.PathName}";
271
+ string marker = Path.Combine(folder, "model.txt");
272
+ if (!File.Exists(marker) || !File.ReadAllLines(marker).Contains(line))
273
+ File.AppendAllLines(marker, new[] { line });
274
+ }
275
+ catch
276
+ {
277
+ // The identity record is best-effort; never block an export on it.
278
+ }
279
+ }
280
+
249
281
  private static string SanitizeFileName(string name)
250
282
  {
251
283
  var invalid = Path.GetInvalidFileNameChars();
@@ -4,14 +4,32 @@ This folder tree is the working area for Pi + Revit sessions. The pi-revit tools
4
4
  Revit bridge add-in; Revit 2025, 2026, or 2027 must be running with a project open
5
5
  (only `ping` and `search_api_docs` work without a document).
6
6
 
7
- ## Conventions
7
+ ## File rules — where every file goes
8
8
 
9
- - One subfolder per Revit project under `Projects\`; start Pi from inside the project folder so
10
- sessions, notes, and outputs stay scoped to that project.
11
- - Save exports, captured view PNGs, scripts, and analysis results inside the current project
12
- folder (e.g. an `exports\` subfolder) — not in temp, not in the model's directory.
13
- - Keep per-project knowledge (naming conventions, known model quirks, decisions) in the project
14
- folder's own `AGENTS.md` so every session starts informed.
9
+ Work sorts by model, automatically. The export tool files its output under the model it came
10
+ from — never a decision for you or the user to make:
11
+
12
+ ```text
13
+ Documents\pi-revit\
14
+ ├─ AGENTS.md <- this file
15
+ ├─ pi-revit.cmd <- double-click launcher
16
+ └─ Models\
17
+ └─ <model title>\ <- created automatically by the tools, one folder per Revit model
18
+ ├─ model.txt <- the model's identity (GUID + file path), written by the add-in
19
+ ├─ exports\ <- export_documents output (its default)
20
+ ├─ captures\ <- view snapshots worth keeping
21
+ └─ scripts\ <- generated scripts and analysis for that model
22
+ ```
23
+
24
+ 1. **Let exports sort themselves**: call `export_documents` without `output_dir` — files land
25
+ in `Models\<model title>\exports` automatically, keyed to the exported document. Pass
26
+ `output_dir` only when the user names a different target.
27
+ 2. **Anything else you produce about a model goes into that model's folder**: view captures the
28
+ user wants to keep in `Models\<model title>\captures` (`capture_view` writes to temp — copy
29
+ the PNG over; the model title comes from `get_model_overview`), scripts and analysis in
30
+ `Models\<model title>\scripts`. Create these subfolders on first use.
31
+ 3. **Never create files loose in the workspace root.** The root holds `AGENTS.md`,
32
+ `pi-revit.cmd`, `Models\`, and Pi's own session data — nothing else, ever.
15
33
 
16
34
  ## Tool habits
17
35
 
@@ -1,31 +1,12 @@
1
- @echo off
2
- rem pi-revit: open Pi in the pi-revit workspace from anywhere.
3
- rem pi-revit -> Documents\pi-revit (workspace AGENTS.md loads)
4
- rem pi-revit <project> -> Documents\pi-revit\Projects\<project> (its AGENTS.md loads too)
5
- rem any further args are passed straight to pi (e.g. pi-revit sample -c)
6
- rem Installed next to the pi command by scripts\setup-workspace.ps1, which rewrites
7
- rem the WORKSPACE line below to the chosen -WorkspaceDir.
8
-
9
- set "WORKSPACE=%USERPROFILE%\Documents\pi-revit"
10
-
11
- if "%~1"=="" (
12
- cd /d "%WORKSPACE%"
13
- pi
14
- exit /b
15
- )
16
-
17
- if exist "%WORKSPACE%\Projects\%~1\" (
18
- cd /d "%WORKSPACE%\Projects\%~1"
19
- shift
20
- ) else (
21
- cd /d "%WORKSPACE%"
22
- )
23
-
24
- set "ARGS="
25
- :collect
26
- if not "%~1"=="" (
27
- set "ARGS=%ARGS% %1"
28
- shift
29
- goto collect
30
- )
31
- pi%ARGS%
1
+ @echo off
2
+ rem pi-revit: open Pi in the pi-revit workspace from anywhere. All arguments are
3
+ rem passed straight to pi (e.g. pi-revit -c continues the last session).
4
+ rem Model output needs no foldering decision: the Revit tools file each export
5
+ rem under Models\<model title>\ automatically, keyed by the document it came from.
6
+ rem Installed next to the pi command by scripts\setup-workspace.ps1, which rewrites
7
+ rem the WORKSPACE line below to the chosen -WorkspaceDir.
8
+
9
+ set "WORKSPACE=%USERPROFILE%\Documents\pi-revit"
10
+
11
+ cd /d "%WORKSPACE%"
12
+ pi %*
@@ -1,8 +0,0 @@
1
- # Project: (name)
2
-
3
- Notes for Pi sessions on this Revit project. Replace/extend as you learn the model.
4
-
5
- - Model: (file name / what it is)
6
- - Units: (metric/imperial)
7
- - Naming conventions: (levels, views, sheets)
8
- - Known quirks: (warnings to ignore, in-place families, etc.)