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.
- 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>
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>
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>
Replace importmap pointing at esm.sh/unpkg with locally-bundled files
built from pinned npm packages (package.json + lockfile). Run
`cd forgejo && npm install && npm run build` to regenerate after a
version bump. Tracked in ifcurl-dkz: fast-xml-parser CVEs in
@thatopen/components 3.3.1 should be addressed in a follow-up upgrade.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Client-side BCF generation cannot resolve IFC GlobalIds from a selector
string. When a selector is present, POST to /bcf instead — the service
runs the selector through IfcOpenShell and writes resolved GUIDs into the
viewpoint. Fails visibly if unreachable; no silent fallback to a GUIDless
file. Also adds /bcf to the Nginx proxy block in forgejo/README.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
render_service.py: new FastAPI app with /render, /select, /render_diff
endpoints that wrap run_sandboxed — listens on a Unix domain socket.
service.py: imports the three pipeline functions from render_service.py;
delegates to render service via httpx when IFCURL_RENDER_SOCKET is set,
falls back to direct run_sandboxed when unset (single-service mode).
__main__.py: add 'render-service' subcommand (--socket PATH).
pyproject.toml: add httpx to service optional deps.
ifcurl-api.service: renamed from ifcurl-preview.service; sets
IFCURL_RENDER_SOCKET, adds AF_UNIX to RestrictAddressFamilies.
ifcurl-render.service: new hardened unit — AF_UNIX only, ~execve
~execveat blocked, no credentials, separate ifcurl-render user.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ifcmerge defaults to preserving remote IDs; --prioritise-local preserves local
IDs instead. For Forgejo merge commits, %A is main (local) so ifcmerge_ours
(--prioritise-local) is the right driver — main's IDs are preserved and the
PR branch is renumbered. For developer rebases from main, %B is main (remote)
so the plain ifcmerge driver (no flag) preserves main's IDs by default.
Update /etc/gitattributes to use ifcmerge_ours for server-side merges, and
update README with a direction table clarifying which driver to use when.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Makes explicit which features need the Go patch (markdown preview only) vs
which are static assets that survive Forgejo upgrades without recompilation.
Documents that the Nginx proxy is required for PR diff images because the
browser fetches them and can't reach localhost directly, and notes that most
production deployments already have Nginx for TLS anyway.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Case 3 in footer.tmpl detects /{owner}/{repo}/pulls/{N}/files, fetches base/
head SHAs from the Forgejo API, then injects <img src="/render_diff?…"> below
the file header of each .ifc file in the diff. Returns early so Case 2 (history
page) does not also run on the PR diff page.
README documents the required Nginx proxy for /preview and /render_diff, and
clarifies that PREVIEW_SERVICE_URL is server-side-only (localhost:8000 is
correct for it); the browser-side diff images need the proxy.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Investigation confirmed: Forgejo's git merge-tree --write-tree (git ≥2.38)
does invoke configured merge drivers for .ifc files.
Key finding: bare repositories do NOT read committed .gitattributes — the
merge driver is silently skipped without a system-wide core.attributesFile.
Changes:
- server-config/gitattributes: new file to deploy at /etc/gitattributes,
containing "*.ifc merge=ifcmerge"
- server-config/gitconfig-ifcmerge: adds [core] attributesFile = /etc/gitattributes
and explains the bare-repo constraint
- forgejo/README.md: rewrites ifcmerge section with investigation findings,
deployment steps, and distinction between server-side vs client-side setup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- forgejo/server-config/ifcurl-preview.service: systemd unit for the preview
service with dedicated user, EnvironmentFile for cache config, and
--allowed-hosts in ExecStart
- forgejo/server-config/gitconfig-ifcmerge: registers two [merge] driver
variants (ifcmerge and ifcmerge_ours) for the asymmetric .ifc merge case
- forgejo/README.md: systemd deployment section (manual + service), ifcmerge
section covering Perl script install, driver registration, per-repo
gitattributes, and merge-direction constraint (merge-commit preserves main's IDs)
- README.md: remove stale "IFC file proxy" description; update quick-summary
to show systemd install path
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The preview endpoint is co-hosted with a specific Forgejo instance, so it
should only be allowed to fetch from that host.
- Local file transport (ifc:///path) is always rejected with 403 — the service
must not read from the server's own filesystem
- New --allowed-hosts CLI option for `ifcurl serve` takes a comma-separated
list of permitted git hostnames (e.g. git.example.com or localhost:3000);
any unlisted host is rejected with 403
- Defense-in-depth: literal private/loopback/link-local IP addresses are
blocked even without an allowlist (169.254.x.x, 127.x, RFC1918, etc.)
- README and forgejo/README.md updated to include --allowed-hosts in the
standard deployment invocation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add the missing Go source files and a README covering the full apply
procedure. Previously only custom assets and the test file were tracked
here; ifc_url.go and the two-file diff were only in the Forgejo tree.
- forgejo/modules/markup/markdown/ifc_url.go — goldmark extension source
- forgejo/go.patch — diff for markdown.go + markup.go (7 lines total)
- forgejo/README.md — step-by-step: apply patch, run tests, build,
deploy assets, configure app.ini, upgrade procedure
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>