@cadcrawl/cad-browser 0.3.0
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/LICENSE.md +5 -0
- package/README.md +65 -0
- package/bin/cad-browser +4 -0
- package/dist/client/assets/index-C1XW2UmF.css +1 -0
- package/dist/client/assets/index-HFIcPO3j.js +204 -0
- package/dist/client/index.html +14 -0
- package/package.json +62 -0
- package/src/analyzer.js +31 -0
- package/src/args.js +16 -0
- package/src/cache.js +38 -0
- package/src/cli.js +53 -0
- package/src/file-types.js +15 -0
- package/src/main.jsx +567 -0
- package/src/path-safety.js +15 -0
- package/src/project-store.js +127 -0
- package/src/reveal-file.js +36 -0
- package/src/scanner.js +75 -0
- package/src/server.js +103 -0
- package/src/styles.css +435 -0
package/LICENSE.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# @cadcrawl/cad-browser
|
|
2
|
+
|
|
3
|
+
A local engineering file browser for STEP, STL, 3MF, PDF, images, and the rest of a project repository. It gives a large folder the browsing experience of a focused desktop application without uploading project files anywhere.
|
|
4
|
+
|
|
5
|
+
Run it inside any project folder:
|
|
6
|
+
|
|
7
|
+
```powershell
|
|
8
|
+
npx @cadcrawl/cad-browser
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or point it at a folder:
|
|
12
|
+
|
|
13
|
+
```powershell
|
|
14
|
+
npx @cadcrawl/cad-browser C:\engineering\project
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
CAD Browser opens `http://127.0.0.1:6767` and provides:
|
|
18
|
+
|
|
19
|
+
- A collapsible project tree and searchable grid/list views.
|
|
20
|
+
- Global search across filenames, paths, and extracted PDF text.
|
|
21
|
+
- File-type filtering and sorting by name, modification date, size, or type.
|
|
22
|
+
- Adjustable tile density from 4 to 15 columns.
|
|
23
|
+
- Open files with their default desktop application.
|
|
24
|
+
- Reveal files in Windows Explorer, macOS Finder, or the platform file manager.
|
|
25
|
+
- Copy project-relative paths and rebuild stale metadata from the inspector.
|
|
26
|
+
- Generated STEP, STL, and 3MF previews.
|
|
27
|
+
- First-page PDF drawing previews.
|
|
28
|
+
- Bounding boxes, geometry counts, materials, and face colors when available.
|
|
29
|
+
- Deduplicated STEP model structure.
|
|
30
|
+
- PDF page count and a short extracted-text preview.
|
|
31
|
+
- A persistent machine-wide cache outside the project directory.
|
|
32
|
+
|
|
33
|
+
## How it works
|
|
34
|
+
|
|
35
|
+
The selected folder is scanned locally. Supported engineering files are analyzed in a small background queue, so the browser opens immediately while previews appear progressively.
|
|
36
|
+
|
|
37
|
+
Cached analysis and PNG renders are stored under:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
~/.cadcrawl/cad-browser/projects/
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The project itself is not modified. Cached data is reused while the file size and modification time match. CAD render files also use the source-hash sidecar validation provided by `@cadcrawl/cad-toolbox`.
|
|
44
|
+
|
|
45
|
+
## Keyboard shortcuts
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
Ctrl/Cmd + K Focus project search
|
|
49
|
+
Escape Close preview, clear search, or close the inspector
|
|
50
|
+
Arrow keys Move through visible files
|
|
51
|
+
Enter Open the selected preview
|
|
52
|
+
O Open the selected file in its default application
|
|
53
|
+
R Reveal the selected file in the system file manager
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Options
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
--port <number> Local port, default 6767
|
|
60
|
+
--host <address> Bind address, default 127.0.0.1
|
|
61
|
+
--no-open Do not open the browser automatically
|
|
62
|
+
--help Show command help
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
All project analysis stays local. CAD and PDF extraction is powered by `@cadcrawl/cad-toolbox`.
|
package/bin/cad-browser
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{color:#252623;background:#f3f2ee;font-family:Segoe UI Variable Text,Segoe UI,sans-serif;font-size:14px;font-synthesis:none;--paper: #fbfaf7;--panel: #f5f4ef;--sidebar-bg: #efeee9;--ink: #252623;--muted: #71736d;--faint: #9a9c96;--line: #deddd7;--line-soft: #e9e8e2;--accent: #2f6657;--accent-soft: #e4eee9;--sidebar: 250px;--inspector: 360px}*{box-sizing:border-box}html,body,#root{min-width:1024px;min-height:100%;margin:0}body{overflow:hidden}button,input,select{font:inherit}button,select{color:inherit}button:focus-visible,input:focus-visible,select:focus-visible,article:focus-visible{outline:2px solid rgba(47,102,87,.45);outline-offset:2px}.app-shell{height:100vh;display:grid;grid-template:56px calc(100vh - 56px) / var(--sidebar) minmax(480px,1fr) var(--inspector);background:var(--panel)}.app-shell.sidebar-collapsed{grid-template-columns:0 minmax(480px,1fr) var(--inspector)}.topbar{grid-column:1 / -1;z-index:10;display:grid;grid-template-columns:minmax(270px,1fr) minmax(360px,620px) minmax(270px,1fr);align-items:center;padding:0 14px;background:#fbfaf7fa;border-bottom:1px solid var(--line)}.brand,.top-actions,.search,.status-pill{display:flex;align-items:center}.brand{gap:9px;font-size:14px;font-weight:650}.brand-mark{display:grid;place-items:center;width:30px;height:30px;color:#fff;background:#2b2d29;border-radius:7px}.project-chip{max-width:180px;padding:4px 8px;overflow:hidden;border-radius:5px;background:#efede7;color:var(--muted);font-size:12px;font-weight:500;text-overflow:ellipsis;white-space:nowrap}.search{height:36px;gap:9px;padding:0 10px;color:var(--muted);background:#efeee9;border:1px solid transparent;border-radius:7px}.search:focus-within{background:#fff;border-color:#bbbdb6;box-shadow:0 0 0 3px #2f665714}.search input{flex:1;min-width:0;border:0;outline:0;background:transparent;color:var(--ink);font-size:13px}.search input::placeholder{color:#92948e}.search button{display:grid;padding:2px;border:0;background:transparent;cursor:pointer}.search kbd,.shortcut-list kbd{padding:2px 6px;border:1px solid #d8d7d1;border-bottom-color:#c8c7c1;border-radius:4px;background:#f8f7f3;color:#777972;font-family:inherit;font-size:10px;box-shadow:0 1px #d6d5cf}.top-actions{justify-content:flex-end;gap:9px}.icon-button{display:grid;place-items:center;width:32px;height:32px;padding:0;border:1px solid var(--line);border-radius:6px;background:var(--paper);cursor:pointer}.icon-button:hover{background:#efeee9}.icon-button.quiet{border-color:transparent;background:transparent;color:var(--muted)}.status-pill{gap:7px;padding:5px 9px;border:1px solid var(--line);border-radius:999px;color:var(--muted);font-size:11px}.status-dot{width:6px;height:6px;border-radius:50%;background:#4f8968;box-shadow:0 0 0 3px #e2eee6}.sidebar{min-width:0;display:grid;grid-template-rows:46px 1fr 48px;overflow:hidden;background:var(--sidebar-bg);border-right:1px solid var(--line)}.sidebar-collapsed .sidebar{opacity:0;pointer-events:none}.sidebar-head{display:flex;align-items:center;justify-content:space-between;padding:0 10px 0 15px;color:var(--muted);font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase}.tree-scroll{padding:2px 7px 14px;overflow:auto}.tree-row{width:100%;height:31px;display:flex;align-items:center;gap:7px;padding:0 7px 0 calc(5px + var(--depth) * 15px);border:0;border-radius:5px;background:transparent;color:#54564f;font-size:12px;text-align:left;cursor:pointer}.tree-row:hover{background:#ffffffa6}.tree-row.active{background:#dcddd7;color:#242521;font-weight:600}.tree-toggle{display:grid;width:14px;color:#898b84}.tree-label{min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tree-count{color:#999b95;font-size:10px;font-variant-numeric:tabular-nums}.sidebar-footer{display:flex;align-items:center;gap:15px;padding:0 15px;border-top:1px solid var(--line);color:#8b8d87;font-size:10px}.sidebar-footer strong{color:#555750}.sidebar-reveal{position:fixed;z-index:15;left:12px;top:68px;display:grid;place-items:center;width:34px;height:34px;padding:0;border:1px solid var(--line);border-radius:7px;background:var(--paper);box-shadow:0 5px 18px #1e201c1f;cursor:pointer}.workspace{min-width:0;overflow:auto;background:var(--paper)}.content-head{position:sticky;z-index:4;top:0;min-height:108px;display:flex;align-items:flex-end;justify-content:space-between;gap:24px;padding:20px 26px 18px;background:#fbfaf7f5;border-bottom:1px solid var(--line-soft);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}.content-title{min-width:0}.breadcrumbs{display:flex;align-items:center;gap:4px;margin-bottom:8px;color:var(--faint);font-size:11px}.breadcrumbs button{max-width:170px;padding:0;overflow:hidden;border:0;background:transparent;color:inherit;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.breadcrumbs button:hover{color:var(--ink)}.content-head h1{margin:0;overflow:hidden;color:#292a26;font-family:Georgia,Times New Roman,serif;font-size:25px;font-weight:500;letter-spacing:-.035em;text-overflow:ellipsis;white-space:nowrap}.content-head p{margin:5px 0 0;color:var(--muted);font-size:12px}.browser-toolbar{display:flex;align-items:center;gap:7px}.dropdown,.sort-control,.grid-scale,.view-switcher{height:32px;display:flex;align-items:center;border:1px solid var(--line);border-radius:6px;background:#f3f2ed;color:#686a64}.dropdown{position:relative}.dropdown-trigger{height:30px;display:flex;align-items:center;gap:6px;padding:0 8px;border:0;border-radius:5px;background:transparent;color:#5c5e58;font-size:11px;cursor:pointer}.dropdown-trigger>span{white-space:nowrap}.dropdown.open .dropdown-trigger,.dropdown-trigger:hover{background:#fff;color:var(--ink)}.dropdown-menu{position:absolute;z-index:20;top:calc(100% + 5px);left:0;min-width:100%;padding:5px;border:1px solid #d6d7d1;border-radius:7px;background:#fff;box-shadow:0 10px 28px #1e201c24}.dropdown-menu button{width:100%;min-width:130px;height:30px;display:flex;align-items:center;justify-content:space-between;gap:16px;padding:0 8px;border:0;border-radius:5px;background:transparent;color:#555750;font-size:11px;text-align:left;cursor:pointer}.dropdown-menu button:hover{background:#f1f2ee;color:var(--ink)}.dropdown-menu button.selected{color:#28584b;font-weight:650}.sort-control .dropdown{border:0;background:transparent}.sort-control .dropdown-trigger{padding-left:8px}.sort-control>button,.grid-scale button,.view-switcher button{display:grid;place-items:center;height:30px;padding:0;border:0;border-radius:5px;background:transparent;color:#74766f;cursor:pointer}.sort-control>button{width:29px;border-left:1px solid var(--line);border-radius:0 5px 5px 0}.grid-scale button{width:27px}.grid-scale button:hover:not(:disabled),.view-switcher button:hover,.sort-control>button:hover{background:#fff;color:var(--ink)}.grid-scale button:disabled{opacity:.28;cursor:default}.grid-scale span{min-width:25px;color:#62645e;font-size:10px;text-align:center;font-variant-numeric:tabular-nums}.grid-scale span:after{content:" col";color:#999b95}.view-switcher{padding:1px}.view-switcher button{width:29px;height:28px}.view-switcher button.active{background:#fff;color:var(--ink);box-shadow:0 1px 3px #1e201c1f}.file-grid{display:grid;grid-template-columns:repeat(var(--grid-columns, 4),minmax(0,1fr));gap:15px;padding:20px 26px 40px}.file-card{min-width:0;overflow:hidden;border:1px solid var(--line-soft);border-radius:8px;background:#fff;cursor:default;opacity:0;transform:translateY(4px);animation:reveal .25s ease forwards;animation-delay:var(--delay);transition:border-color .14s,background-color .14s}@keyframes reveal{to{opacity:1;transform:translateY(0)}}.file-card:hover{border-color:#bfc1ba;background:#fdfdfa}.file-card.selected{border-color:#4f7b6c;background:#fbfdfc}.thumb{position:relative;aspect-ratio:4 / 3;display:grid;place-items:center;overflow:hidden;background:#f4f3ef;border-bottom:1px solid var(--line-soft)}.thumb img{width:100%;height:100%;object-fit:contain}.placeholder{width:100%;height:100%;display:grid;place-content:center;justify-items:center;gap:8px;color:#878a83}.placeholder span{font-family:Georgia,Times New Roman,serif;font-size:11px;font-style:italic;font-weight:400}.placeholder.kind-cad{color:#557568;background:#edf2ef}.placeholder.kind-pdf{color:#9a5b49;background:#f4ece8}.placeholder.kind-image{color:#636d82;background:#eceff3}.type-badge{position:absolute;left:8px;top:8px;padding:3px 6px;border:1px solid rgba(40,42,37,.12);border-radius:4px;background:#ffffffe6;color:#64665f;font-size:9px;font-weight:700;letter-spacing:.055em;text-transform:uppercase;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px)}.processing{position:absolute;inset:auto 8px 8px;display:flex;align-items:center;gap:6px;padding:6px 8px;border-radius:5px;background:#242621d6;color:#fff;font-size:10px}.processing svg,.analysis-note svg,.loading-screen>svg{animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.file-copy{padding:10px 11px 11px}.file-name{overflow:hidden;color:#31322e;font-size:12px;font-weight:620;text-overflow:ellipsis;white-space:nowrap}.file-copy span{display:block;margin-top:4px;overflow:hidden;color:var(--muted);font-size:10px;font-variant-numeric:tabular-nums;text-overflow:ellipsis;white-space:nowrap}.file-grid.density-compact{gap:8px;padding-inline:18px}.file-grid.density-compact .file-copy{padding:7px}.file-grid.density-compact .file-name{font-size:10px}.file-grid.density-compact .file-copy span{font-size:8px}.file-grid.density-compact .type-badge{left:5px;top:5px;padding:2px 4px;font-size:7px}.file-grid.density-micro{gap:5px;padding-inline:13px}.file-grid.density-micro .file-card{border-radius:5px}.file-grid.density-micro .file-copy{padding:5px 6px 6px}.file-grid.density-micro .file-name{font-size:8px}.file-grid.density-micro .file-copy span{display:none}.file-grid.density-micro .type-badge{left:3px;top:3px;padding:1px 3px;border-radius:3px;font-size:6px}.file-list{padding:13px 26px 36px}.file-list .file-card{display:grid;grid-template-columns:88px minmax(0,1fr);margin-bottom:7px}.file-list .thumb{height:68px;aspect-ratio:auto;border:0;border-right:1px solid var(--line-soft)}.file-list .placeholder svg{width:23px}.file-list .placeholder span,.file-list .type-badge{display:none}.file-list .file-copy{align-self:center}.inspector{min-width:0;overflow-y:auto;background:#f8f7f3;border-left:1px solid var(--line)}.empty-inspector{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:36px;color:var(--muted);text-align:center}.inspector-empty-mark{display:grid;place-items:center;width:44px;height:44px;border:1px solid var(--line);border-radius:10px;background:#fff;color:#787a74}.empty-inspector h2{margin:15px 0 5px;color:var(--ink);font-family:Georgia,Times New Roman,serif;font-size:18px;font-weight:400}.empty-inspector p{max-width:250px;margin:0;font-size:12px;line-height:1.55}.shortcut-list{width:210px;display:grid;grid-template-columns:1fr auto;align-items:center;gap:8px 12px;margin-top:22px;color:#7e807a;font-size:11px;text-align:left}.inspector-head{min-height:61px;display:grid;grid-template-columns:36px minmax(0,1fr) 32px;align-items:center;gap:10px;padding:11px 11px 11px 14px;border-bottom:1px solid var(--line-soft)}.inspector-title{min-width:0}.inspector-title strong,.inspector-title span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.inspector-title strong{color:#2b2c28;font-size:13px;font-weight:650}.inspector-title span{margin-top:3px;color:var(--muted);font-size:11px}.type-icon{display:grid;place-items:center;width:36px;height:36px;border-radius:8px;background:#e8e7e1;color:#656760}.type-icon.kind-cad{background:#e2ece7;color:#46705f}.type-icon.kind-pdf{background:#f0e3dd;color:#9a513d}.inspector-preview{position:relative;width:calc(100% - 28px);aspect-ratio:4 / 3;display:grid;place-items:center;margin:14px;padding:0;overflow:hidden;border:1px solid var(--line);border-radius:8px;background:#f0efea;cursor:zoom-in}.inspector-preview:disabled{cursor:default}.inspector-preview img{width:100%;height:100%;object-fit:contain}.inspector-actions{display:grid;grid-template-columns:1.3fr 1fr 34px;gap:7px;margin:-1px 14px 14px}.inspector-actions button{height:34px;display:flex;align-items:center;justify-content:center;gap:7px;padding:0 9px;border:1px solid #cccec7;border-radius:6px;background:#fff;color:#4c4e48;font-size:11px;font-weight:600;cursor:pointer}.inspector-actions button:hover{border-color:#aeb1a9;background:#fdfdfb}.inspector-actions .primary-action{border-color:#315f52;background:#315f52;color:#fff}.inspector-actions .primary-action:hover{background:#274f44}.analysis-note,.error-note{margin:0 14px 13px;padding:10px 11px;border-radius:6px;font-size:12px;line-height:1.45}.analysis-note{display:flex;align-items:center;gap:8px;background:#e5eee9;color:#4e695e}.error-note{background:#f2e3df;color:#884534}.inspector-section{padding:17px 18px 18px;border-top:1px solid var(--line-soft)}.inspector-section h3{margin:0 0 12px;color:#656861;font-size:11px;font-weight:700;letter-spacing:.065em;text-transform:uppercase}.property,.vector{min-height:32px;display:flex;align-items:center;justify-content:space-between;gap:14px;font-size:13px}.property span,.vector span{color:var(--muted)}.property strong{overflow:hidden;color:#292a27;font-weight:600;text-align:right;text-overflow:ellipsis}.vector code{color:#4f514b;font-family:Cascadia Mono,Consolas,monospace;font-size:11px}.dimension-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:7px;margin-bottom:9px}.dimension-strip div{min-width:0;padding:10px;border-radius:6px;background:#ebeae5}.dimension-strip span,.dimension-strip strong{display:block}.dimension-strip span{margin-bottom:4px;color:#898b85;font-size:10px;font-weight:700}.dimension-strip strong{overflow:hidden;color:#292a27;font-size:13px;font-variant-numeric:tabular-nums;text-overflow:ellipsis}.swatches{display:grid;gap:8px}.swatch{display:grid;grid-template-columns:22px 1fr auto;align-items:center;gap:9px;font-size:12px}.swatch>span{width:22px;height:22px;border:1px solid rgba(0,0,0,.14);border-radius:5px}.swatch code,.model-tree{font-family:Cascadia Mono,Consolas,monospace}.swatch code{font-size:11px}.swatch small{color:var(--muted);font-size:11px}.material-name{margin-bottom:7px;font-size:12px;font-weight:600}.text-preview{max-height:180px;overflow:auto;margin-top:8px;padding:11px;border-radius:6px;background:#eeede8;color:#4e504a;font-family:Georgia,Times New Roman,serif;font-size:13px;line-height:1.6;white-space:pre-wrap}.model-tree{max-height:240px;margin:0;overflow:auto;padding:11px;border-radius:6px;background:#ebeae5;color:#474944;font-size:11px;line-height:1.65;white-space:pre}.inspector-footer{padding:14px 18px 20px;border-top:1px solid var(--line-soft)}.inspector-footer button{display:flex;align-items:center;gap:7px;padding:0;border:0;background:transparent;color:#60635c;font-size:11px;cursor:pointer}.inspector-footer button:hover{color:var(--ink)}.modal-backdrop{position:fixed;z-index:30;top:0;right:0;bottom:0;left:0;display:grid;place-items:center;padding:38px;background:#1e201c94;-webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px);animation:fade-in .14s ease}@keyframes fade-in{0%{opacity:0}}.preview-modal{width:min(1100px,91vw);height:min(820px,89vh);display:grid;grid-template-rows:58px 1fr;overflow:hidden;border:1px solid rgba(255,255,255,.2);border-radius:10px;background:#f8f7f3;box-shadow:0 28px 80px #14151257}.modal-head{display:flex;align-items:center;justify-content:space-between;padding:0 12px 0 18px;border-bottom:1px solid var(--line)}.modal-head strong,.modal-head span{display:block}.modal-head strong{font-size:13px}.modal-head span{margin-top:3px;color:var(--muted);font-size:11px}.modal-canvas{min-height:0;display:grid;place-items:center;padding:24px;background:#e9e8e3}.modal-canvas img{max-width:100%;max-height:100%;object-fit:contain;box-shadow:0 10px 34px #23242029}.empty-state{grid-column:1 / -1;min-height:300px;display:flex;flex-direction:column;align-items:center;justify-content:center;color:var(--muted);text-align:center}.empty-state h2{margin:12px 0 4px;color:var(--ink);font-family:Georgia,Times New Roman,serif;font-size:18px;font-weight:400}.empty-state p{max-width:390px;margin:0;font-size:12px;line-height:1.5}.loading-screen{height:100vh;display:flex;align-items:center;justify-content:center;gap:10px;background:var(--paper);color:var(--muted);font-size:13px}.toast{position:fixed;z-index:40;left:50%;bottom:22px;display:flex;align-items:center;gap:8px;padding:9px 12px;border:1px solid rgba(255,255,255,.13);border-radius:7px;background:#252722f0;color:#fff;font-size:12px;box-shadow:0 10px 30px #191a1738;transform:translate(-50%)}.toast.error{background:#773226f5}@media(max-width:1220px){:root{--sidebar: 220px;--inspector: 330px}.content-head,.file-grid,.file-list{padding-inline:18px}.browser-toolbar{gap:5px}}
|