29 Commits
Author SHA1 Message Date
Dylan M. Taylor 996bf871cd fix(security): prevent symlink traversal in asset walker, safe cert tmpdir, and atomic icon copy (#1255) 2026-10-24 04:36:46 -04:00
BFlat 3476f4b1e7 Merge pull request #1244 from storytold/batch/r2-1
Community batch r2-1: 63 reviewed PRs
2026-10-24 11:15:53 +07:00
a1a842af9a chore: resolve SonarCloud maintainability issues (#1241)
* chore: resolve SonarCloud maintainability issues

- Define SHA256_FMT constant in packaging script to remove duplicated string literal (shelldre:S1192)
- Remove redundant 'static lifetime annotations from const items (rust:S8863)
- Replace closures with method and function pointers (rust:S1612)
- Extract helper functions in synthetic document generation, bezier polyline flattening, and component restoration to reduce cognitive complexity (rust:S3776)

* fix(packaging): use verify_sha256 helper function to avoid shellcheck SC2059

* fix(engine): remove duplicate closing brace in large_document

* fix(engine): take &mut Document in restore_id_map; keep 'static on associated consts

restore_id_map allocates ids, so it needs a mutable document. Elided
lifetimes in associated consts trip elided_lifetimes_in_associated_constant,
so those annotations are restored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Assign positional parameters to locals in sha256 verification

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Dylan Taylor <dylan@craftmaker.dev>
2026-10-23 23:28:13 -04:00
zuujiscomandClaude Opus 5.5 5d9f8a53a3 Merge main into freebsd/aarch64-cross-package
Resolves the package.sh conflicts with main's SonarCloud cleanup: the cross-build changes are kept
and use main's style, with [[ ]] tests and release_arch taking its argument as a named local and
ending in an explicit return.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 19:06:00 -05:00
aiongg c48102350b Packaging: pin the signing client and appimagetool, and check their hashes (#950)
* Packaging: pin the Windows signing client and check its hash

* Packaging: pin appimagetool and check its hash

* Reject AppImage download for architectures without a pinned appimagetool

* Pin the AppImage runtime
2026-10-23 13:02:11 -04:00
Dylan M. Taylor e66780a39b packaging: use [[ for bash conditional tests (SonarCloud S7688) (#1225)
SonarCloud flags every bare [ conditional in bash scripts under packaging/ as a reliability smell (rule S7688). Convert the flagged [ ... ] tests to [[ ... ]]: safer word-splitting and no glob surprises, same semantics for these string and file tests.
2026-10-23 12:56:34 -04:00
Dylan M. Taylor 8d790607ff packaging: bash test and function hygiene (SonarCloud S7688, S7679, S7682, S131, S7677) (#1201)
- Use [[ ]] instead of [ ] for conditional tests in the bash packaging scripts (S7688). Every
  converted test compares quoted values to literals, so no pattern-matching change.
- Name positional parameters with locals inside functions (S7679).
- End the env.sh helpers with an explicit return that keeps their exit status (S7682).
- Give case statements a default branch (S131).
- Send the check-app-specific.sh error to stderr (S7677).

packaging/freebsd/package.sh is left alone while #1158 rewrites it.
2026-10-23 11:17:32 -04:00
zuujiscom 03354ec7d3 FreeBSD package.sh: accept only the two supported FreeBSD targets
Review follow-up. CARGO_BUILD_TARGET must be aarch64-unknown-freebsd or x86_64-unknown-freebsd,
the two the release builds; anything else, including made-up triples such as
aarch64-foo-unknown-freebsd, stops with exit 2.

Part of storytold/craft-common-actions#39.
2026-10-22 16:06:19 -05:00
zuujiscom 30149d765d FreeBSD package.sh: never run a FreeBSD target's binary on another OS
Review follow-up. With CARGO_BUILD_TARGET set on a host that is not FreeBSD (say an x86_64 Mac
building x86_64-unknown-freebsd), the architectures match but the binary still cannot run, so
the --version run is skipped there and the file(1) check is used instead.

Part of storytold/craft-common-actions#39.
2026-10-22 15:31:37 -05:00
zuujiscom 477b25e63f FreeBSD package.sh: accept only executables in the cross-build check
Review follow-up. The file(1) check for binaries that cannot run here now needs an executable
(file says "executable" or "pie executable") or an ELF with an interpreter, which is how an older
file(1) still shows a PIE it calls a shared object. FreeBSD libraries, object files and core files
for the target architecture are refused.

Part of storytold/craft-common-actions#39.
2026-10-22 14:49:35 -05:00
zuujiscom e366f61e8f FreeBSD package.sh: accept only FreeBSD targets, check cross-built binaries
Review follow-up. CARGO_BUILD_TARGET must now be a *-unknown-freebsd triple, so a Linux or macOS
target can no longer be packaged under a FreeBSD name, and it is read before uname -m, so an
unsupported host does not block a valid cross build. When the binaries are for another
architecture and cannot run --version, file(1) must report each as a FreeBSD ELF executable
for the target architecture.

Part of storytold/craft-common-actions#39.
2026-10-22 14:32:12 -05:00
zuujiscom 27ea0d4bdc FreeBSD package.sh: package the aarch64 cross build
The release workflow now cross-compiles FreeBSD aarch64 inside the x86_64 VM
(storytold/craft-common-actions#50) and sets CARGO_BUILD_TARGET=aarch64-unknown-freebsd.
package.sh now reads the binaries from target/<triple>/release when CARGO_BUILD_TARGET
is set, names the archive after the target instead of uname -m, and skips the --version
run when the binary is for another architecture than the machine. x86_64 packages are
unchanged.

Part of storytold/craft-common-actions#39.
2026-10-22 14:14:09 -05:00
Dylan M. Taylor cb7966556c security: enforce HTTPS on curl downloads (SonarCloud S6506) (#1016)
Add --proto '=https' to curl invocations so redirects cannot downgrade to
plaintext HTTP. Resolves SonarCloud S6506 (shell/docker/githubactions).
2026-10-21 19:36:11 -04:00
skylartaylor d9584410af ci: retain FigCraft package and metadata checks 2026-10-16 05:24:23 +02:00
bflatastic e100c165fb #346: FreeBSD's desktop entry matches the window class there (the binary's name) 2026-10-15 19:02:40 +07:00
bflatastic 370d9f7adc Merge main and the community batch into #346 2026-10-15 19:00:48 +07:00
IanHollow 212438a6e3 Set the native window identity to match the desktop entry
Assisted-by: OpenAI Codex (GPT-6)
Signed-off-by: IanHollow <72767437+IanHollow@users.noreply.github.com>
2026-10-14 13:12:38 -07:00
tydude001andClaude Opus 5.5 1c1b699598 packaging: RPM declares the glibc 2.35 floor, so RHEL 9 refuses it
FigCraft's RPM declares no glibc floor, though the deb has `libc6 (>= 2.35)`. On Rocky Linux 9
(glibc 2.34) the RPM installs, and then `figcraft-cli` fails with ``/lib64/libm.so.6: version
`GLIBC_2.35' not found``.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 13:35:50 -05:00
MuhammadyusufandClaude Opus 5.5 dd3d4d326c feat(packaging): run figcraft-cli from the AppImage with cli <args> (#232)
The AppImage ships figcraft-cli in usr/bin, but AppRun only ever launched the
app, so the CLI (and its MCP server) could not be reached without extracting
the image. `FigCraft.AppImage cli mcp` now execs `figcraft-cli mcp`, skipping
desktop integration because the CLI is headless.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 09:30:42 +07:00
BFlat c5830e4683 Release: retry stapling and its validation on macOS (#164)
Apple's notarization ticket service dropped the connection in two release runs in a row
(once while validating the stapled DMG, once while stapling), failing the macOS job after a
successful build, signing and notarization. Stapling and its validation now try up to five
times, 15 s apart.
2026-10-12 21:41:02 +07:00
bflatastic 98c4753118 M9: open hosting: fair limits for shared addresses
Third review:
- a broadcast counts once per recipient block, welcomes don't count
  against block caps, and presence, cursor chat and pings have their own
  per-address budget, so an office behind one address works together
- when everyone's reading budget runs out, the biggest readers are cut
  off until it fits (their bytes freed at once), no cliff
- block counters are forgotten once only the table holds them
- install.sh: root's downloads, clone, swap file and built binary in a
  root-only directory; the build user builds its own copy; the binary is
  copied out with the build user's rights
- recommended open-mode settings in install.sh's config and the docs
2026-10-12 11:40:03 +07:00
bflatastic e0435d4eb4 M9: close the remaining open-hosting DoS paths
Second security review:
- a broadcast counts once against the queued-bytes budget; each block of
  addresses gets at most an eighth; when the budget runs out the biggest
  consumer is shed, not the receiver
- forced compactions at most once a minute per file
- plugin downloads check the per-address share before the global budget
  and before reading
- install.sh never replaces a Caddyfile with other sites (one import line,
  once; install-test.sh in packaging lint); the built binary runs only as
  the server's account
- bytes being read count against per-block and global budgets, the
  biggest readers dropped first
- block multipliers x2 (/56) and x4 (/48), connection caps at most a
  sixteenth/eighth of all; global publish and download budgets eight times
  a /48's share
- problems capped at 200; writes refused below max(1 GiB, two files) free;
  the private-server file cap documented
2026-10-12 11:40:03 +07:00
bflatastic 7edc61b8d2 M9: harden open hosting against resource exhaustion
Fixes from the security review of the public server:
- team libraries only in key-published files on open servers; unpacking
  bounded by the file cap (zip bombs refused)
- byte-bounded send queues per connection and in all, a bound on bytes
  waiting for the hub, per-address and global download budgets
- batches checked against the file, per-address and total caps as files
  grow (refused with a Reject the app rolls back); the core's recent-batch
  memory bounded in bytes; nothing confirmed when a log can't be written
- usage reports kept in memory; per-kind message caps checked while read
- layered IPv6 limits (/64, /56, /48), a global publish rate, connections
  reserved for sessions, short idle timeout for one-shot requests
- revoked links and removed files cut library connections
- data directory 0700, server key 0600 from creation
- install.sh: SSH ports from sshd, ufw left off when other services
  listen, unprivileged builds of the latest tag, settings checked before
  use, own Caddy snippet; systemd memory and network caps; backups check
  free space and say they hold the key
- linger reads raw bytes after an oversized frame (tungstenite asserted)
2026-10-12 11:40:03 +07:00
bflatastic faf2e78c9d M9: install.sh, backup timer and docs for a public figcraft-server
packaging/server/install.sh sets up Debian/Ubuntu behind Caddy: binary from
its release archive, the source tree it sits in, the latest release or a
clone (temporary swap under 2 GB of memory), user, dirs and config only when
missing, systemd unit, Caddy site, nightly backup timer, ufw for 22/80/443;
safe to re-run for upgrades. docs/server.md gains Running a public server
(limits, expiry, moderation, operator responsibility, no end-to-end
encryption, threat model) and an install.sh walk-through; protocol, MCP,
CLI and parity docs updated.
2026-10-12 11:40:03 +07:00
BFlat 76df2d4136 M9: hosting figcraft-server: wss in the desktop app, server releases, deployment guide (#125)
The desktop app joins wss:// sessions (rustls with webpki roots, certificates always checked, clear errors; FIGCRAFT_CA_FILE for private authorities), with one TLS session shared by the reader and writer threads. figcraft-server stops gracefully on SIGTERM/SIGINT/SIGHUP/Ctrl+C, ships in Linux x86_64/aarch64 release archives, and docs/server.md gains a Deploy on a Linux server guide with a hardened systemd unit, Caddyfile, nginx config and Dockerfile in packaging/server.
2026-10-11 15:52:27 +07:00
BFlatandClaude Opus 5.5 435415770f M9: live sessions in the browser; join links and dialog polish (#106)
- Browser client (step 4): the web build joins sessions a desktop app hosts
  through the browser's WebSocket API (web-sys, binary frames, the same
  message encoding). Its connection logic is a target-independent state
  machine (collab-net driver.rs): hello on open, changes and presence held
  until the welcome, throttled presence, keep-alive pings, a silent host
  counted as dropped, reconnect with backoff, final refusals. Tested natively
  against a scripted socket and a real host over loopback. Hosting stays
  desktop-only (LiveLink::can_host; collab.peers canHost). https pages are
  told up front that they can only reach ws:// sessions on this computer.
- Shared join logic (join.rs: GuestConfig, outcomes, taking in host messages)
  and transport limits (limits.rs) used by the native guest and the browser.
- Invite links: `figcraft figcraft://join?...` joins on start (a bad link
  opens the Join dialog with it); file:// arguments are paths. Windows
  registers a per-user figcraft:// opener (HKCU\Software\Classes\figcraft)
  behind a Registry trait (tests use a fake): collab.registerLinks {on?} and a
  Preferences checkbox, default on for installed builds, never for builds
  from source. macOS Info.plist declares CFBundleURLTypes; the Linux desktop
  entry declares x-scheme-handler/figcraft and passes %U.
- Join dialog: Escape closes it and no longer reaches the canvas (selection
  kept); its field has the keyboard when it opens.
- Docs: collab-protocol (browser client, links, mixed content), mcp,
  control-protocol, README, web hosting notes, collaboration wording in the
  progress docs (numbers unchanged).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 09:10:59 +07:00
Brandon ThomasandClaude Opus 5.5 a2bf43927f Release prep: 0.3.0 and linux-riscv64 release job (#108)
* Release prep: bump to 0.3.0; add linux-riscv64 release job

- release.yml: new linux-riscv64 job (cross-compiled on ubuntu-24.04 against ports.ubuntu.com
  riscv64 libraries, tar.gz only, CLI smoke-tested under qemu-riscv64), ported from GridCraft;
  the release job needs it so SHA256SUMS covers its tarball.
- packaging/linux/package.sh: CROSS_ARCH / CROSS_TARGET / CROSS_COMPILE / EMULATOR support.
- Version 0.2.0 -> 0.3.0 (cargo xtask version set), Cargo.lock refreshed.
- docs/releasing.md, docs/hardware-parity.md: list the riscv64 tarball.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* CI: tell actionlint about the org's github-ubuntu-16core runner label

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 19:42:22 -04:00
Brandon ThomasandClaude Opus 5.5 38a30d6aaf Packaging: fix AppRun test categories leftover
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:34:42 -04:00
Brandon ThomasandClaude Opus 5.5 b36fd771ab M0.9: MCP server + figcraft-cli, PDF export, web app, release/CI packaging, vector edit mode, workspace lint cleanup
- crates/mcp: JSON-RPC MCP server (18 tools, resources, prompts), headless and attached backends, end-to-end agent tests
- apps/figcraft-cli: info/export/convert/render/run/commands/mcp/perf
- crates/pdf: vector PDF export via krilla with embedded text; file.exportFramesPdf
- apps/figcraft-web + packaging/{macos,windows,linux,freebsd,web} + release/ci workflows
- engine vectoredit: edit points/handles/bend/add/delete-heal; canvas overlay and edit strip

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:31:53 -04:00