Commit graph

116 commits

Author SHA1 Message Date
Claude
6bcabc26e4
Add beads for query and clash features
New issues:
- ifcurl-8rf (P2): Server /query endpoint + _sandboxed_query
- ifcurl-19h (P2): Renderer clash visibility mode
- ifcurl-2iv (P3): Viewer query results table (blocked on ifcurl-8rf)
- ifcurl-4u3 (P3): Viewer query creation/editing UI
- ifcurl-982 (P3): Viewer clash visibility mode display

https://claude.ai/code/session_01NBsytCd6L7UQPiKbcLn4kn
2026-05-09 08:09:10 +00:00
fdaf02a880
Merge pull request #5 from brunopostle/claude/review-spec-coverage-cM3AC
Add SessionStart hook to install bd and bootstrap beads in web sessions
2026-05-09 10:00:25 +02:00
Claude
8693bb5c90
.claude: add SessionStart hook to install bd and bootstrap beads
Installs bd (beads issue tracker) via go install and bootstraps the
embedded Dolt database from the git-tracked issues.jsonl on each fresh
web session, where the embeddeddolt/ directory is absent.

Bootstrap sequence:
  1. go install github.com/steveyegge/beads/cmd/bd@latest (if absent)
  2. Temporarily point sync.remote to the HTTP git origin so bootstrap
     can create the embedded Dolt schema (Dolt wire-protocol clone fails
     over HTTP/1.1 but that is expected and handled)
  3. Restore .beads/config.yaml and .beads/issues.jsonl from git before
     any bd auto-export can overwrite them
  4. bd config set issue_prefix ifcurl triggers auto-import of the full
     issues.jsonl into the initialised but empty database

Also adds bd to PATH via CLAUDE_ENV_FILE and sets beads.role=contributor
to suppress the role-not-configured warning.

https://claude.ai/code/session_01CKpkhWhzkzR5K5PDSR8N5F
2026-05-09 07:55:30 +00:00
35e064fe90
Merge pull request #4 from brunopostle/claude/review-spec-coverage-cM3AC
SPECIFICATION.md: add query parameter and visibility=clash
2026-05-09 09:28:50 +02:00
Claude
c02ccfe5dd
url.py, test_url.py: add query parameter and visibility=clash
- IfcUrl gains a query field (str | None) for dot-notation
  attribute/property paths (e.g. Pset_WallCommon.FireRating)
- visibility now accepts 'clash' in addition to the existing three modes
- to_string() serialises both new fields
- 10 new tests covering query parsing, pset paths, combined query+view,
  clash visibility, roundtrip serialisation, and the new spec examples

https://claude.ai/code/session_01CKpkhWhzkzR5K5PDSR8N5F
2026-05-09 07:27:35 +00:00
Claude
98c258d0cc
SPECIFICATION.md: add query parameter and visibility=clash
Adds two new parameters to address GitHub issues #2 and #3:

- `query`: dot-notation path (e.g. Pset_WallCommon.FireRating) that
  returns a {GlobalId: value} JSON object for the selected elements.
  Restricted to rooted entities; additive with view parameters so a
  viewer can show both a 3D view and a property table simultaneously.

- `visibility=clash`: visual-cue-only rendering style that marks
  selected elements with clash-indicator styling. No semantic claim;
  exports to BCF as highlight since BCF has no structural equivalent.

Updates §3, §7, and §8 accordingly.

https://claude.ai/code/session_01CKpkhWhzkzR5K5PDSR8N5F
2026-05-09 07:22:55 +00:00
5edf2b8b6f viewer: show status hint when clip mode is active
Displays "Double-click model surface to place clip plane" in the status
bar when clip mode is toggled on, clears it when toggled off.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 22:30:24 +01:00
81d3a3b6cb bcf_api: add topic filtering; documents_api: add GET /document-metadata
BCF list_topics now maps topic_status, assigned_to, label, modified_after,
modified_before query params to Forgejo issue API params.

documents_api adds GET /document-metadata/{document_id} which decodes the
document_id and proxies Forgejo's contents endpoint for file metadata.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 22:24:52 +01:00
b4e051ecb7 beads: add OpenCDE completion issues (topic filtering, doc metadata, OAuth2, picker) 2026-04-29 21:39:54 +01:00
931fa2a303 beads: update issue tracker state
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 20:48:01 +01:00
a111c430f3 documents_api: implement OpenCDE Documents API 1.0
POST /documents/1.0/document-versions resolves document_ids (base64url
encoding of owner/repo/path) to versioned download URLs. Exposes only
git tags + the current HEAD commit — mirrors CDE conventions where only
released versions are visible, while still surfacing the WIP state.

version_number is the tag name for releases and short SHA for HEAD.
Tagged SHAs are deduplicated so HEAD at a tag doesn't create a duplicate.
Download URLs point at Forgejo's existing raw/commit endpoint.

Auth forwarded verbatim. No Go code, no Forgejo recompilation.
Proxy at /documents/ on the Forgejo hostname.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 20:27:25 +01:00
fcd8d24e74 beads: close ifcurl-b1c 2026-04-29 19:39:22 +01:00
90f003a587 bcf_api: implement BCF 3.0 REST API as Python routes in the preview service
Stateless translation layer over Forgejo issues and comments. Auth is
forwarded verbatim (Authorization: Bearer), so Forgejo enforces per-user
permissions with no service token. Viewpoints are ifc:// URLs stored in
comment bodies; GUIDs are deterministically derived from Forgejo IDs and
are reversible without a lookup table.

Endpoints: GET/POST projects, topics, comments, viewpoints; PUT topic;
GET viewpoint snapshot (proxied through preview service).

Also adds ifc_url_to_bcf_viewpoint() to bcf.py (symmetric counterpart of
bcf_viewpoint_to_ifc_url), and fixes rate-limit state leaking between tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 19:38:34 +01:00
fea6b37beb beads: close ifcurl-lwl 2026-04-29 19:21:48 +01:00
ed03c13d36 service: add GET /foundation/versions OpenCDE discovery endpoint
Returns the Foundation API 1.1 version document listing BCF 3.0 and
Documents 1.0 API base URLs. Public, no auth required. Derives the
public base URL from X-Forwarded-Host/X-Forwarded-Proto headers so it
works correctly behind an nginx/Caddy reverse proxy with no extra config.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 19:20:54 +01:00
f14669c129 beads: close ifcurl-l50 2026-04-29 19:10:20 +01:00
427a0e6d74 docs: document bcf_viewpoint_to_ifc_url() and IfcUrl.to_string()
Update SPECIFICATION.md §6 to clarify the isolate-visibility mapping
(DefaultVisibility=false + Exceptions). Add library usage examples to
README for to_string() and bcf_viewpoint_to_ifc_url().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 19:07:53 +01:00
2de4af5f4d bcf: add bcf_viewpoint_to_ifc_url() and IfcUrl.to_string()
Implements SPECIFICATION.md §6 BCF→ifc:// direction: parse a BCF 3.0
REST viewpoint dict (camera, clips, selection/visibility) and apply it
to a base IfcUrl to produce an ifc:// URL string.

IfcUrl.to_string() serialises any IfcUrl back to a valid ifc:// URL,
enabling round-trip parse→to_string for all URL forms.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 19:04:04 +01:00
387618a593 readme: add OpenCDE phases to roadmap
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 00:12:24 +01:00
0e73e20683 spec: add OpenCDE transport extension to ifc:// scheme
Extends the ifc:// URL scheme to address IFC documents hosted on
OpenCDE-compliant Common Data Environments, using document_id= and
version_index= query parameters as the transport signal and version
reference respectively. Adds §9 covering resolver workflow, OAuth2
discovery via Foundation API, caching rules, and federation notes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:33:52 +01:00
ea9ccc3c72
Merge pull request #1 from OpeningDesign/forgejo/local-setup-docker
forgejo: add Docker-based local setup guide and Dockerfile
2026-04-28 00:02:33 +01:00
950349941c forgejo: add @thatopen/components-front, fix click-to-identify and model overview
Bundle OBCF (components-front) alongside OBC so Highlighter is sourced from the
correct package.  Update click handler to use item.getGuid() — GlobalId is no
longer in the attributes map in fragments 3.4.x.  Fix populateMetaPanel crash
(ClassificationGroupData now wraps ids in a .map property, not a plain object).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 00:01:19 +01:00
889645c2b2 forgejo: fix missing View in 3D button on commit file view pages
On /src/commit/{hash}/file.ifc pages, breadcrumb anchors match the
a[href*="/src/commit/"] selector before the Permalink anchor, returning
a directory URL that parseCommitHref rejects (no file path). Fix by
trying window.location.pathname first — it parses correctly when already
on a commit file URL — and only falling back to a Permalink anchor search
for branch/tag file views. Add a regression test for directory-level
commit hrefs returning null.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 20:31:43 +01:00
d60bd044dd forgejo: add JS unit tests, extract pure functions into viewer-util.js
Extract parseCommitHref, isSimpleTypeSelector, subtractIdMap, and
isCommitHash into a new viewer-util.js ES module so they can be tested
without a browser. Convert ifcurl.js from an IIFE to an ES module
importing from viewer-util.js; update footer.tmpl to type="module".

Add node:test suites for viewer-url.js (32 tests) and viewer-util.js
(28 tests). Add npm test script and document it in the build section.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 20:24:58 +01:00
Ryan Schultz
d7dd4f1ea1 forgejo: add Docker-based local setup guide and Dockerfile
Add forgejo/SETUP_LOCAL.md documenting a self-contained local deployment
of Forgejo + ifcurl on Windows using Docker Desktop. Covers Nginx reverse
proxy for PR diff images, correct Forgejo v15 custom paths (/data/gitea),
libosmesa6 for headless rendering, and a git URL rewrite so the ifcurl
container can clone repos from localhost:3000 via the Docker-internal
forgejo hostname.

Add docker/Dockerfile for the ifcurl preview service.

Link SETUP_LOCAL.md from README.md and forgejo/README.md.
2026-04-27 12:26:58 -05:00
a1a7a6c829 forgejo: handle ifc:// markdown links in JS, eliminate required Go compile
- ifcurl.js: scan a[href^="ifc://"] at page load and replace with preview
  figures — works with [title](ifc://...) syntax without any Go extension
- viewer.js: Issue button now emits [title](ifc://...) markdown link syntax
  instead of a bare URL, so shared views render as previews without the patch
- README: document no-rebuild quick setup path; Go patch section is now optional

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 08:25:34 +01:00
27156a5906 forgejo: extract footer.tmpl inline JS into ifcurl.js asset
footer.tmpl now just loads /assets/ifcurl.js; all injection logic lives in
the new ifcurl.js file alongside the other viewer assets. Update deploy
instructions in both READMEs; fix incorrect /etc/forgejo path in top-level README.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 07:36:57 +01:00
9c7b07e753 docs: reorganise README to lead with Forgejo features
Move visual diffs, inline previews, viewer, and collaboration workflow to
the top. ifc:// URL spec, Python library, and preview service follow as
supporting detail. Add missing items: storey isolation, ref autocomplete,
visibility dropdown, /select and /render_diff endpoints, cache CLI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 07:32:12 +01:00
7e9e814a4b viewer: add ifc:// URL links and clickable images to embedded snapshots
- ifc_url.go: wrap figcaption URL in <a href="ifc://"> for future protocol handler
- footer.tmpl: wrap diff snapshot images in viewer links; add ifc:// URL anchor below each snapshot (Cases 3 and 4)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 07:05:14 +01:00
4e84a2beda beads: update issue tracker state
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:38:10 +01:00
36f528a254 viewer: extract inline JS into viewer.js
viewer.html was ~1250 lines of almost entirely JavaScript. The script
block is now a single <script type="module" src="./viewer.js"> tag,
leaving viewer.html as pure HTML/CSS (~238 lines).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 15:50:28 +01:00
3dd804ffc7 viewer: fix five P3 bugs (types, clip, ref nav, ortho, BCF snapshot)
- Types panel: fix count by iterating groupData directly (groupData.map
  was undefined — FragmentIdMap is the groupData value, not a wrapper)
- Clip planes: register OBC.Raycasters for the world before setupClipper
  so clipper.create(world) can raycast against the model surface
- Ref navigation: ▾ button now navigates when input already has a value;
  add change listener alongside input for cross-browser datalist coverage
- Orthographic projection: replace missing controls.setOrthoCamera() with
  world.camera.projection.set("Orthographic") + threeOrtho scale fix;
  refresh threeCamera reference after projection switch
- BCF export: capture rendererCanvas snapshot and include snapshot.png in
  the BCF zip with a <Snapshot> reference in markup.bcf

Closes: ifcurl-07d, ifcurl-1pa, ifcurl-66h, ifcurl-xy9, ifcurl-uo9

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 14:07:52 +01:00
63eaa63611 viewer: add 'All storeys' reset row to storey filter (ifcurl-0n8)
Add a permanent 'All storeys' row at the top of the Storeys list in the
model overview panel. It starts active (all visible) and clicking it
restores full model visibility. Clicking any storey row then back to
'All storeys' is now always possible, even after switching between storeys.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 09:40:25 +01:00
58219fa2e3 viewer: fix copy-URL button position, selector width, and issue link protocol
- Move ⎘ copy-URL button immediately after the URL text box (ifcurl-2m9)
- Widen selector field from flex:1 to flex:2 (ifcurl-mts)
- Use window.location.origin for the new-issue link, removing hardcoded https:// (ifcurl-njq)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 08:49:47 +01:00
dd0fb2c365 viewer: fix load transition — snapshot appears before navigation blank
Show the canvas snapshot on the current page (z-index 9999) immediately
before navigating, so the browser's between-pages blank is hidden behind
the static image. Navigate without delay. Remove the body fadeIn animation
that was making the snapshot on the new page invisible during the 0.2s
fade-in, causing the visible blank-then-snapshot sequence.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 08:29:32 +01:00
be1395649c viewer: fix visibility modes, add dropdown, zoom-all, and load transition
- visibility=highlight: apply orange colour overlay to selected elements
  (all others visible normally) using FragmentsManager.highlight() directly
  — OBC.Highlighter is in @thatopen/components-front which is not installed
- visibility=ghost: dim non-selected elements to 15% grey opacity
- visibility=isolate: unchanged (hider.isolate)
- Add 'show' dropdown (highlight/ghost/isolate) that appears when a
  selector is set; changing it reloads with the new visibility= param
- Add 'fit' button: calls cameraControls.fitToBox(model.box, true)
- Smooth load transition: capture canvas snapshot (preserveDrawingBuffer)
  before navigation, display it as an overlay on the new page, fade it
  out once the model has rendered

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 08:17:34 +01:00
c7c5d35c63 forgejo: regenerate go.patch with ServiceToken field
Amended forgejo commit now includes ServiceToken in the IfcURL config
struct. Regenerated patch from that commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 00:37:15 +01:00
3d3fcd6f8e beads: update issue state — close ifcurl-irp, ifcurl-3sz, ifcurl-d7m; reopen ifcurl-d7m
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 00:26:25 +01:00
7aa4ef85ab viewer: fix visibility=highlight — show all elements, highlight selection
Previously applySelector always called hider.isolate() which hid all
non-selected elements regardless of visibility mode. For highlight mode,
set up the Highlighter before applying the selector and use
highlightByID("select") instead so all elements remain visible with the
selection highlighted in orange.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 00:20:51 +01:00
837a9d10c8 render: fix render_diff — tuple unpack, IfcProduct filter, diff-area zoom
- git.py: unpack (repo, is_stale) tuple from _get_repo() in diff_text;
  was AttributeError 'tuple has no attribute commit' on every render_diff
- render.py: filter removed_entities and _entity_bounds include list to
  IfcProduct only; non-geometric entities (IfcTaskTime etc) crash the
  ifcopenshell geom iterator
- render.py: replace reset_camera(bounds=diff_bounds) with explicit camera
  positioning; pyvista's reset_camera re-expands clipping to all actors
  so the full scene remained visible — now camera is repositioned at the
  default viewing direction but at a distance sized to the diff bounds,
  zooming tightly to just the changed elements

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 23:54:35 +01:00
134bd4d887 docs: fix asset deploy path in forgejo/README.md
Custom assets go to /var/lib/forgejo/custom/public/assets/, not
/etc/forgejo/public/assets/ which Forgejo does not serve from.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 23:12:15 +01:00
bcf9d58470 service: fix preview pipeline for local Forgejo deployment
- auth.py: catch OSError (not just FileNotFoundError) so ProtectHome=yes
  doesn't crash token lookup — returns None and falls back to anonymous
- git.py: wipe partial bare-clone dir before HTTP fallback so git can retry
  after HTTPS fails (port 443 not available on local HTTP-only Forgejo)
- pyproject.toml: add python-multipart to service deps (FastAPI form data)
- ifcurl-api.service: fix ExecStart path (/opt/ifcurl), set allowed-hosts
  to localhost, add MPLCONFIGDIR to silence matplotlib cache warning
- ifcurl-render.service: fix ExecStart path, add CacheDirectory + MPLCONFIGDIR
- nginx-ifcurl.conf: new file tracking the nginx reverse-proxy config;
  listen on [::]:80 so IPv6 loopback requests reach the Forgejo proxy block

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 23:10:35 +01:00
6045df2bc6 viewer: inject render_diff thumbnail on commit page for .ifc changes
On /owner/repo/commit/{sha} pages, Case 4 injects an image below the
diff-file-header of each IFC file: render_diff for modifications,
plain preview for adds and deletes.  Parent SHA is read from the
existing "parent" commit link in the DOM — no extra API calls.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 21:07:07 +01:00
2fdb442fcf beads: close ifcurl-tq8 2026-04-25 20:48:58 +01:00
4df69d229d tests: add TestCacheCli covering list, clear, and prune CLI paths
9 tests exercise _cmd_cache() directly with fake cache dirs and a
monkeypatched user_cache_dir, covering output formatting, empty states,
prune with --max-gb arg, prune via IFCURL_CACHE_MAX_GB env, and the
error exit when neither is set.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 20:43:43 +01:00
ab4fb6ded9 viewer: ref picker with branch/tag datalist and camera-preserving navigation
The ref input now has a datalist populated from the Forgejo branches+tags
API on load. A ▾ button clears and focuses the field to expose all refs.
Selecting a datalist option auto-navigates; pressing Enter in any structured
field now preserves camera/clip/fov/scale from the current URL so switching
refs keeps the same viewpoint.

Closes ifcurl-4rj.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 20:29:17 +01:00
e66460fb13 service+viewer: add /select endpoint for complex selector resolution
New GET+POST /select endpoint resolves an ifc:// URL selector to a JSON
list of GlobalIds, with T3 caching. The viewer now detects non-type-name
selectors (property filters, Name=, pset notation) and falls back to a
/select round-trip, applying the returned GUIDs via getLocalIdsByGuids().

Closes ifcurl-ov6.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 20:20:41 +01:00
14c8412074 viewer: add model metadata panel with type counts and storey isolation
A new '☰' toolbar button opens a panel showing the IFC type breakdown
(sorted by element count) and storey list. Clicking a storey isolates
its elements via OBC.Hider; clicking again restores full visibility.

Closes ifcurl-dag.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 20:04:43 +01:00
a5d14222a5 viewer: show commit-pin badge + branch-switch button when ref is a hash
When an ifc:// URL uses a bare commit hash as the ref the toolbar now
shows an amber badge with the abbreviated hash and (after a Forgejo API
lookup) a '→ heads/main' button that reloads with the branch-tip ref.

Closes ifcurl-gy8.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 19:19:37 +01:00
fce198580a viewer: upgrade three/web-ifc/@thatopen to latest — partial CVE fix
three 0.177→0.184, web-ifc 0.0.75→0.0.77, @thatopen/components
3.3.1→3.4.2, @thatopen/fragments 3.3.1→3.4.3, + new camera-controls
3.1.2 peer dep. Reduces fast-xml-parser findings from 2 critical to
1 high + 1 low; remaining issues are upstream in @thatopen >= 3.3.3
with no fix released yet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 18:59:02 +01:00